try/catch ブロック内で作成されたオブジェクトが、メソッドの残りの部分のスコープ内にないのはなぜですか?
彼らです。ブロック内で宣言された変数try/catch
は、含まれているブロックのスコープ内にはありません。これは、他のすべての変数宣言が、それらが発生するスコープに対してローカルであるのと同じ理由で、仕様で定義されている方法です。:-) (あなたのコメントへの返信を含む以下の詳細。)
外部からアクセス可能な内に作成されたオブジェクトを次に示します。try/catch
SomeObject someObject = null;
try
{
someObject = new SomeObject();
someObject.dangerousMethod();
}
catch(Exception e)
{
}
someObject.anotherMethod(); // This is fine -- unless the SomeObject
// constructor threw the exception, in which
// case someObject will be null
違いに注意してください。変数が宣言されている場所は、オブジェクトが作成された場所ではなく、変数が存在するスコープを定義します。
しかし、上記のメソッド名などに基づいて、そのためのより有用な構造は次のようになります。
SomeObject someObject = new SomeObject();
try
{
someObject.dangerousMethod();
}
catch(Exception e)
{
}
someObject.anotherMethod();
あなたのコメントについて:
try/catch ブロック用に別のスコープが作成された理由について、私は混乱していると思います。
Java では、すべてのブロックがスコープを作成します。の本体、の本体、if
の本体など — これらはすべて、ネストされた新しい変数スコープを作成します。else
while
if (foo) {
SomeObject bar = new SomeObject();
}
bar.doSomething(); // <== Compilation error, `bar` is not defined
(実際、制御構造を持たないブロックでも作成されます。)
考えてみれば、それは理にかなっています。 if
orの本体を定義するブロックのように、一部のブロックは条件付きwhile
です。上記のif
では、bar
( の値に応じてfoo
) が宣言されている場合と宣言されていない場合がありますが、もちろんコンパイラには の実行時値の概念がないため、これは意味がありませんfoo
。おそらく一貫性を保つために、Java の設計者は、すべてのブロックが新しいネストされたスコープを作成するようにしました。( JavaScriptの設計者は別の方法をとっています。ブロック スコープは追加されていますが、まだまったくありません。また、このアプローチは人々を混乱させます。)