2012-01-05 18 views
9

これは私が書いたコードです。なぜcatchブロックはJavaで初期化されていない変数でエラーを出しますか?

int num; 
try { 
    num=100; 
    DoSomething(); 
    System.out.println(num); 
} catch(Exception e) { 
    DoSomething1(); 
} finally{ 
    DoSomething2(); 
} 
System.out.println(num); // Error Line 

私が言及したエラー行で 'ローカル変数numが初期化されていない可能性があります。'というエラーが発生します。 catchブロックを削除すると、エラーが消えます。ここで何が間違っていますか?間違っていることをしていますか?

+0

関連する、確か。 :) –

答えて

10

tryブロックに例外がスローされた場合、変数numは実際には初期化されていない可能性があります。ブロックcatchを含めると、実行はエラーラインに関係なく続行でき、コンパイラはエラーを報告します。

catchブロックを削除すると、例外がなくても実行が「エラーライン」に達し、この場合、変数はtry内で初期化されます。

+0

はい、私はそれを知っています、興味深いのは、catchブロックを削除するとエラーが消え去ったという事実でした。 – gizgok

+0

@gizgok Davidはこう答えました。「catchブロックを削除すると、例外がなくても実行が「エラーライン」に達し、この場合、変数はtry内で初期化されます。 " +1 btw –

+0

はい。あなたの説明がうまくいくことを願っています。 –

2

Javaのローカル変数は自動的には初期化されません。したがって、それらを使用する前に初期化する必要があります。詳細はフォア

int num=0; 
try 
{ 
    .. 
} 
... 

読む - Definite Assignment (JLS - 16.2.15 try Statements)

+1

しかし、彼は 'num = 100;'で初期化しています。実行パスにも分岐はありません( 'else else'文はありません)。 javaは 'num'が' 100'であることを知るべきです。 –

+1

@Rosdi - これはtryブロック内にあります。 – adatapost

+0

私は初期化の部分について知っている、私はより多くのcatchブロックの削除エラーにつながる方法に興味があります。 – gizgok

0

問題が int型NUM = -1、numをinitializatedされていないということです。 エラーが消える;

+0

しかし、例外がスローされる前に、 'num = 100'という代入が実行されます。だからキャッチブロックは常に*割り当ての後に*実行されます。 –

+0

@AVDは "Javaのローカル変数は自動的には初期化されません" – DVD

+0

はい、変数**は**アクセスされる前に初期化されます。 –

3

例外処理は、コンパイラを混乱させることができます(私は...あなたは既にそれらを使用する前に、ローカル変数をintialiseする必要性について知っていると仮定している、とあなたはcatchブロックに気づいた行動に焦点を当てています)。この場合、は、変数numが設定される前に例外がスローされる可能性があることを知っていますが、コンパイラはこれを認識しません。

numが設定される前に例外がスローされる可能性があるとコンパイラは考えています。この場合、try-catchブロックの外側に出力しようとするとnumは初期化されません。

+1

割り当てが実行されない可能性はありません。あるケースについては@ FabianBarneyの例を参照してください。 –

3

Javaでは、ローカル変数を初期化する必要があります。 tryブロック内のローカル変数を初期化する前に例外がスローされ、catchブロック内でvarを初期化しないため、これらのcatchブロックがあるときは保証されません。したがって、ローカル変数はtry-catch-finallyブロックの後に初期化されていない可能性があります。

catchブロックを削除すると、varはtryの後で初期化されるか、例外がスローされ、try-blockの後のコードは決して実行されません。最後に

  • INITをブロックでのtry-ブロックでのtryブロックの前
  • のinit VARを

    • のinit varとキャッチブロック
    • のinit VAR:あなたはこれを修正する可能性を次まし

      varはtry-block内でのみ有効ですが、例外をキャッチしません。

    var initはtが初期化されていても初期化されません彼はあなたがtry-blockでやる最初のことです。たとえば、実行されたスレッドは、try-blockを入力した後、var initの前にThread.stop(Throwable)で停止することができます。これが起こると、varは初期化されずにcatch-finallyが実行され、try-catch-finallyの後にコードが最後に実行されます。ここで

    は、私が何を意味するか表示する例を示します

    public static void main(String[] args) throws InterruptedException { 
        Thread thread = new MyThread(); 
    
        thread.start(); 
        Thread.sleep(100); 
        thread.stop(new Exception()); 
    } 
    
    private static class MyThread extends Thread { 
    
        @Override 
        public void run() { 
         int num = -1; 
    
         try { 
          Thread.sleep(600); //just to hit the thread at the right point 
          num = 100; 
          System.out.println("blub"); 
         } 
         catch (Exception e) { 
          System.out.println("catch"); 
         } 
         finally { 
          System.out.println("finally"); 
         } 
    
    
         System.out.println(num); 
         System.out.println("after all"); 
        } 
    
    } 
    

    このコードが出て出力します。

    catch 
    finally 
    -1 
    after all 
    
  • +0

    例>説明 – yunandtidus

    2

    あなたはyoutはtryブロック内num = 100をパトンている、コンパイラはエラーが前に発生する可能性があることを前提としていnum = 100に達しました。したがって、Catch blochに入力すると、コンパイラはint numと表示され、Variable not initializedエラーが発生します。

    +0

    'num = 100;'行に達する前にエラーが発生する可能性はありますか? –

    +4

    @Rosdiコンパイラの場合、エラーが発生する可能性があります。 JVMの植え付け、内部エラーの生成、... –

    1

    私は昨日これについて要するにhttp://vanillajava.blogspot.com/2012/01/odd-case-of-initialization.html

    をブログに書いているように起こった変数でも最も些細な場合には、のtry/catch内で初期化されている場合、コンパイラは知りません。このため、変数が初期化されていない可能性があると不平を言います。

    興味深いことに、変数をfinalにしてtry/catchブロックの後で変数を設定しようとすると、コンパイラはそれが初期化されている可能性があると不満を持ちます。

    +0

    、非常に面白い変数への最終的な側面の導入。なぜこれが起こるのですか?何か案は? – gizgok

    +0

    最終変数が初期化されていて、try/catchブロックの後に初期化されている場合とされていない場合があります。コンパイラには分かりません。 –

    +0

    'Thread.stop(Throwable)'には、与えられた例でローカルvarが実際には初期化されていない状態に陥ることがあります。 –

    関連する問題