2

これが私たちの問題を説明するためのいくつかのサンプルコードです:

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だと思います(例外がスローされても割り当てが実行された場合など)。これは明らかにバグに関連しており、念のために割り当てのないバージョンをデプロイしますが、あなたの1人もこれに気付いたか、提案する何らかの説明があるかどうかを知りたいと思います。

また、問題のあるJDKでこれを実証するためのサンプルプログラムを作成し、結果を投稿します。

4

6 に答える 6

5

例外が発生した場合、割り当ては絶対に行われるべきではありません。これは、JVM の非常に深刻なバグです。しかし、例外が実際には別の場所 (コンストラクター A() など) で発生しているのではないかと最初に疑っています。

于 2009-10-05T13:54:11.637 に答える
2

a == new A()最適化されていない限り、私は推測します。コードは少しばかげていませんか?

a=1;
a=2;

あなたのコードの意図に合わせて書き直してください:

A a = null;
try {
  a = doSomethingThatWillThrowAnException();
} catch( ... ) {
  a = new A();
}
于 2009-10-05T14:04:29.797 に答える
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()他のユーザーが示唆しているように、コンストラクターで例外がスローされる可能性が最も高いと思います。(そうでない場合は、非常に厄介な防御コードが必要になることを願っています)

于 2009-10-05T14:37:39.957 に答える
0

new A()オプティマイザーが副作用がないことを確認できる場合、最初の割り当てを最適化します。このケースを切り分けるには、JIT を無効にしてコードを再度実行します。a != nullその後、オプティマイザーの不具合が発生している場合。

明らかな修正は、ブロックのnew A()前に追加することです。try

A a = new A();
try {
  a = doSomethingThatWillThrowAnException();
} finally {
  System.out.println("A = " + a);
}
于 2009-10-05T13:54:07.253 に答える
0

コードをコンパイルしてから、バイトコードを見て何が起こっているかを確認できます。http://andrei.gmxhome.de/eclipse/のバイトコード アウトライナー Eclipse プラグインを使用します。

于 2009-10-05T14:21:33.457 に答える