以下是一些示例代码来说明我们的问题:
A a = null;
try {
a = new A();
a = doSomethingThatWillThrowAnException();
} finally {
System.out.println("A = " + a);
}
问题是在finally块中打印的'a'的值是什么......
我不确定,我想我偶然发现了一些可能没有完全描述的内容。我在笔记本电脑上观察到(x86上的jdk1.6.0.16)'a'等于A()。但是,在Solaris上使用JDK 1.4时,我认为该值为null(就好像即使抛出异常也执行了赋值)。这显然与一个错误有关,我们将部署一个没有作业的版本,只是为了确保,但我们想知道你们其中一个人是否也注意到这一点或者提出某种解释。
我们还要做的是制作一个示例程序,以便在有问题的JDK上演示这一点......我们将发布结果。
答案 0 :(得分:4)
当发生异常时,绝对不应该进行分配 - 这将是JVM中一个非常严重的错误。但我首先怀疑异常实际上发生在其他地方(例如在构造函数A()中)。
答案 1 :(得分:2)
我会假设a == new A()
,除非它被优化掉了。这段代码看起来不是很傻:
a=1;
a=2;
也许会改写你的代码:
A a = null;
try {
a = doSomethingThatWillThrowAnException();
} catch( ... ) {
a = new A();
}
答案 2 :(得分:1)
使用以下程序
在Solaris上使用Sun JDK_1.4.2_05进行Solaris测试public class Test {
public static void main(String[] args) throws Exception {
String test = null;
try {
test = "step1";
test = getString();
} finally {
System.out.println(test);
}
}
public static String getString() {
throw new RuntimeException();
}
}
我在控制台中获得了“第1步”。
正如其他用户所建议的那样,我认为最有可能的是A()
构造函数中抛出异常。 (我希望是这样,否则需要一些非常讨厌的防守代码)
答案 3 :(得分:0)
如果优化器可以确保new A()
没有副作用,它将优化第一个分配。要隔离这种情况,请禁用JIT并再次运行代码。如果之后a != null
,您会看到优化程序故障。
显而易见的解决方法是在new A()
阻止之前更多try
:
A a = new A();
try {
a = doSomethingThatWillThrowAnException();
} finally {
System.out.println("A = " + a);
}
答案 4 :(得分:0)
您可以尝试编译代码,然后查看字节码以查看发生了什么。我用 来自http://andrei.gmxhome.de/eclipse/
的字节码大纲eclipse插件答案 5 :(得分:0)
我在Solaris 10上使用JDK 1.4.2运行代码并且它具有正确的行为。问题是生产中的代码不是我正在看的那个......(以前的版本)
阅读你的答案很有意思,因为它清楚地表明优化器故障可能发生,并且最好再次猜测引擎盖下发生了什么。
下次的心理记录:“首先,检查明显:如果你有一个奇怪的行为,你所看到的代码可能不是已执行的代码。”
再次感谢, 塞德里克