0

私は次のコードを持っています:

public class test3    
{
    public static void main(String a[])
    {
        System.out.println("In main");
        System.out.println(new Demo(0).devide());    
    }
}
class Demo
{
    int x;
    Demo(int x)
    {
        this.x=x;
    }
    public int devide()
    {   
        try
        {
            return x/x;
        }
        catch(Exception e)
        {
            System.out.println(e);
            return 4;

        }
        finally
        {
            System.out.println("In finally");
            return 1;
        }    
    }
}

上記のコードでは、出力として 4 を期待していますが、生成される出力は次のとおりです。

In main
java.lang.ArithmeticException: / by zero
In finally
1

だから戻ってくる1

4

8 に答える 8

2

finally は、たとえ が戻ったとしても、常にtry/ブロックを終了する直前に呼び出されます。実際には、inは return in に先行し、 return inは発生しません。詳細と解説はこちらをご覧ください。catchcatchreturnfinallycatchcatch

基本的には、バイトコードに変換する方法に要約されます。のコードは「サブプロシージャ」として扱われ、各出口点で、 /ブロックfinallyを出る直前に、コードの へのジャンプが実行されます。サブプロシージャ ジャンプは実際のプロシージャ コールではないため、サブプロシージャからサブプロシージャが開始されたポイントへの復帰が禁止され、元のプロシージャが実行されることはありません。trycatchjsrfinallyreturnfinallyreturn

をバイトコードに大まかに変換すると、次のdivide()ようになります。

    aload_0
    getfield   // x
    dup
    idiv
    istore_1
    jsr        // to finally block
    iload_1
    ireturn

// catch
    bipush 4
    istore_1
    jsr        // to finally block
    iload_1
    ireturn

// finally
    astore_2   // save the return address
    bipush 1
    ireturn
    ret 2      // dead code

ここで、catch の return が実行されない理由がはっきりとわかります。

于 2013-09-06T07:44:33.467 に答える
2
finally
{

}

他のコードが前に実行されたかどうかに関係なく、最後に実行されます

だから、ついにそれはあなたを返しますが1、実際にはあなたは期待していませんでした:)

于 2013-09-06T07:45:00.680 に答える
2

何が起こるかは次のとおりです。

  1. コードはリターン 4 に達します。
  2. 値 4 が戻りスタックに置かれます
  3. コードはリターン 1 に達します。
  4. 値 1 が戻りスタックに置かれる
  5. メソッドが終了すると、スタックの一番上が返され (したがって値 1)、値 4 が破棄されます。
于 2013-09-06T07:45:18.653 に答える
1

finallyブロックは常に実行されます。たぶん、あなたが電話をかけたらSystem.exit(0)tryそうではないでしょう。tryしかし、他の状況では、 /がどのようにcatch終了したか (通常または突然) に関係なく、そうです。

finally(指定した場合)の戻り値は、try/catch からの戻り値を上書きします。例外についても同じことが言えます - 最終的に独自の例外をスローした場合、try/catch からのものは破棄されます。

于 2013-09-06T07:59:38.913 に答える
1
In above code I expect 4 as output but output generated is :
In main
java.lang.ArithmeticException: / by zero
In finally
1

何を期待していましたか?

最後に、JVM がクラッシュするか、以前に System.exit() を呼び出さない限り、ブロックは常に実行されます。finally ブロックで 1 を返すため、出力として 1 が得られます。

于 2013-09-06T07:45:43.260 に答える
1

JLS 14.20.2 に従ってtry-finally と try-catch-finally の実行:

値が原因でブロックの実行がtry突然完了した場合は、次の選択肢があります。throwV

のランタイム型がステートメントの任意の句のVキャッチ可能な例外クラスと互換性のある代入である場合、最初 (左端) のそのような句が選択されます。選択した句のパラメータに値が代入され、その句のブロックが実行されます。次に、選択肢があります。catchtrycatchVcatchcatch

ブロックが正常catchに完了すると、finallyブロックが実行されます。

于 2013-09-06T07:46:14.783 に答える
0

プログラムの実行制御が try ブロックに入ると、Finally ブロックが実行されます。try ブロックが例外なしで実行されるか、例外なしで実行されるか、return ステートメントを使用している try ブロックで実行されるかに関係なく、JVM はプログラムを終了する前に常に finally ブロックを実行します。元:

 public class test3    
{
    public static void main(String a[])
    {
        System.out.println("In main");
        System.out.println(new Demo(10).devide());    
    }
}
class Demo
{
    int x;
    Demo(int x)
    {
        this.x=x;
    }
    public int devide()
    {   
        try
        {
            return x/x;
        }
        catch(Exception e)
        {
            System.out.println(e);
            return 4;

        }
        finally
        {
            System.out.println("In finally");
            return 1;
        }    
    }
}

上記の pgm は例外なく実行されますが、それでも最終的にブロックが実行されます。

于 2013-09-06T07:58:27.747 に答える
0

この場合4も追加されstackますが、最終的に実行された後、これは返され1ます。1 はスタックの最上位要素であるため、1 しか表示されません。

これをチェックしてください

 try
    {
        return x/x;
    }
    catch(Exception e)
    {
        System.out.println(e);
        x=4;
        return x++;


    }
    finally
    {
        System.out.println("In finally");
        return x;
    }

あなたが見ることができるもの

    In main
    java.lang.ArithmeticException: / by zero
    In finally
    5

これで、値をキャッチして最終的に返すことができますが、スタック内の最上位の要素を見ることができます。

于 2013-09-06T07:46:40.490 に答える