[英]Weird false-positive of javac data flow analysis
我有以下形式的代码:
class Test {
private final A t;
public Test() {
for ( ... : ... ) {
final A u = null;
}
t = new A();
}
private class A {}
}
编译说:
variable t might already have been assigned
有趣的是,如果我对循环执行以下任何更改,它就可以解决了!
A u = null
final A u = null;
) 这里发生了什么?
注意:我无法得到导致错误的最小示例,因此“环境”(大约1400 loc)可能存在问题。 然而,我无法看到可能会扰乱t
初始化的因素,因为t
被写入其他地方。
有趣的事实:IntelliJ IDEA说“变量'你可以拥有'最终'修饰符......”如果我删除它。
我使用javac 1.6.0_26。
更新:你去了,这个例子如此之小:
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;
}
}
}
无法在javac 1.6.0_26
编译,但在javac 1.7.0_02
上javac 1.7.0_02
。 所以我想我打了一些邪恶的角落......某事?
请注意,您可以执行任何操作
A()
删除循环内的final
for
循环替换循环,例如for ( int i=0; i<100; i++ ) { ... }
它会编译。
如果你有很多代码我会尝试这个。
private final A t;
public Test() {
final int t = 1;
for ( ... ) {
final A u = null;
}
this.t = new A();
这将导致“可能”初始化t
任何代码失败(并显示在编译器中)。
如果你的构造函数恰好调用另一个本身不设置t
构造函数,编译器就无法理解。
看到这里 。
由于问题已在Java 7中修复,因此它可能是Java 6编译器中的一个错误。
我的理解是,在最终的var中存储一个对象并不会使你的对象成为不可变的,而是它的引用。 这解释了为什么当你删除它工作的最终关键字时,并且因为删除for循环,我认为你正在访问对象引用而不是实例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.