What language is this for?
Java
Which rule?
java:S1602 “Lambdas containing only one statement should not nest this statement in a block”
Why do you believe it’s a false-positive?
S1602 recommends rewriting () -> { stmt; } as () -> stmt, but when stmt is an invokeExact/invoke call on a void MethodHandle, the rewrite is not semantics-preserving. It compiles but throws WrongMethodTypeException at runtime. invokeExact is signature-polymorphic and infers its return type from the call site: as a statement in a block lambda it’s a void context (matches a (…)void handle), but as an expression lambda targeting a void-returning functional interface, javac infers the return type as Object, so the site becomes (…)Object and no longer matches the handle. S1602 should not raise (or offer the quick-fix) for this construct.
Are you using:
- SonarQube Cloud? Yes (SonarQube Cloud / SonarCloud)
How can we reproduce the problem?
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
public class S1602Repro {
// Functional interface whose single abstract method returns void (e.g. a "run and log on failure" helper).
interface ThrowingRunnable {
void run() throws Throwable;
}
static void call(ThrowingRunnable action) throws Throwable {
action.run();
}
public static void main(String[] args) throws Throwable {
MethodHandle voidHandle = MethodHandles.empty(MethodType.methodType(void.class)); // type ()void
// Block lambda: invokeExact is a statement (void context) -> return type inferred as void -> OK
call(() -> { voidHandle.invokeExact(); });
System.out.println("block lambda: OK");
// S1602 flags the block above and suggests collapsing the braces to this expression lambda.
// It compiles, but throws at runtime:
// java.lang.invoke.WrongMethodTypeException: handle's method type ()void but found ()Object
call(() -> voidHandle.invokeExact());
System.out.println("expression lambda: OK"); // never reached
}
}
Running it prints block lambda: OK, then throws WrongMethodTypeException at the expression-lambda call. Real-world impact: a mechanical S1602 cleanup reintroduced this exact runtime regression in OSHI (freeing a Windows BSTR) — FFM free string failed on windows · Issue #3422 · oshi/oshi · GitHub
I verified this reproducer throws on a stock JDK (25).