问题
I have code of the following form:
class Test {
private final A t;
public Test() {
for ( ... : ... ) {
final A u = null;
}
t = new A();
}
private class A {}
}
Compiler says:
variable t might already have been assigned
Interestingly, if I perform any of the following changes to the loop it works out!
- Change the loop's content to
A u = null
- Remove the loop (but keep
final A u = null;
) - Replace the foreach-style loop with a classic counting loop
What is going on here?
Note: I could not get the minimal example to cause the error so there is probably something wrong with the "environment" (about 1400 loc). I can not see what could disturb the initialisation of t
, though, as t
is written to nowhere else.
Fun fact: IntelliJ IDEA says "Variable 'u' can have 'final' modifier..." if I remove it.
I use javac 1.6.0_26.
Update: There you go, this example so so minimal:
import java.util.List;
class A {
private final boolean a;
public A() {
for ( final Object o : new Object[] {} ) {
final Object sh = null;
}
a = true;
}
class B {
private final Object b1;
private final Object b2;
B() {
b1 = null;
b2 = null;
}
}
}
Fails to compile on javac 1.6.0_26
but compiles on javac 1.7.0_02
. So I guess I hit some wicked corner case of ... something?
Note that you can do any of
- Remove any one member
- Remove
final
inside the loop inA()
- Replace the loop with a normal
for
loop, e.g.for ( int i=0; i<100; i++ ) { ... }
and it will compile.
回答1:
If you have lots of code I would try this.
private final A t;
public Test() {
final int t = 1;
for ( ... ) {
final A u = null;
}
this.t = new A();
This will cause any code which "might" initialise t
to fail (and show up in the compiler.
回答2:
If you're constructor happen to call another constructor that doesn't itself set t
, the compiler fails to understand that.
See here.
回答3:
As the problem is fixed in Java 7, it is probably a bug in the Java 6 compiler.
回答4:
It is my understanding that storing an object in a final var does not make your object immutable but its reference. That explain why when you remove the final keyword it works and as per removing the for-loop, i think you are accessing the object reference and not an instance.
来源:https://stackoverflow.com/questions/9112927/weird-false-positive-of-javac-data-flow-analysis