What version of OpenRewrite are you using?
- org.openrewrite:rewrite-core:8.79.2
- org.openrewrite.recipe:rewrite-static-analysis:2.32.0
What is the smallest, simplest way to reproduce the problem?
FinalizePrivateFields finalizes a private field that is only assigned in the constructor, without checking whether that field is read by a lambda (or anonymous class) captured in another instance field initializer declared earlier. Instance field initializers run in declaration order before the constructor body, so when the field is made final, Java's definite-assignment analysis rejects the read inside the lambda and the rewritten source no longer compiles.
@Test
void finalizePrivateFieldCapturedByLambdaInInstanceInitializer() {
rewriteRun(
spec -> spec.recipe(new FinalizePrivateFields()),
// language=java
java(
"""
import java.util.function.Function;
public class Foo {
private String name;
protected Function<Throwable, Void> logAndAccept =
throwable -> {
System.out.println(name);
return null;
};
public Foo(String name) {
this.name = name;
}
}
"""));
}
After the recipe runs, name is finalized and javac fails:
Foo.java:6: error: variable name might not have been initialized
System.out.println(name);
^
The recipe should skip fields that are read from inside a lambda or anonymous class captured by an instance field initializer whose declaration precedes the field's single constructor assignment.
What version of OpenRewrite are you using?
What is the smallest, simplest way to reproduce the problem?
FinalizePrivateFieldsfinalizes a private field that is only assigned in the constructor, without checking whether that field is read by a lambda (or anonymous class) captured in another instance field initializer declared earlier. Instance field initializers run in declaration order before the constructor body, so when the field is madefinal, Java's definite-assignment analysis rejects the read inside the lambda and the rewritten source no longer compiles.After the recipe runs,
nameis finalized andjavacfails:The recipe should skip fields that are read from inside a lambda or anonymous class captured by an instance field initializer whose declaration precedes the field's single constructor assignment.