20

BlackBerry Java クラスの例で、以下のようなコードを見てきました。

try
{
    // stuff that will throw an exception
}
catch(final Exception e)
{
    // deal with it
}

finalパフォーマンスのためだと思います。Exceptionタイトルのとおり、既にスローされた an を変更する理由はめったに (今までに?) ないため、常にfinal?

もしそうなら、これはコンパイラでできることではありませんか? それとも、コンパイラによって行われ、final手動で追加してもまったく影響はありませんか?

4

5 に答える 5

17

Java 言語仕様 11.2.2では、最終的な例外と最終的でない例外に違いがあります。

スローされた式が静的型 E を持ち、最終または実質的に最終の例外パラメーターではない throw ステートメント (§14.18) は、E またはスローされた式がスローできる例外クラスをスローできます。
[...]
スローされた式が catch 句 C の最終または実質的に最終の例外パラメーターである throw ステートメントは、次の場合に例外クラス E をスローできます。

  • E は、C を宣言する try ステートメントの try ブロックがスローできる例外クラスです。と
  • E は、C のキャッチ可能な例外クラスのいずれかと互換性のある代入です。と
  • E は、同じ try ステートメントで C の左側に宣言されている catch 句のキャッチ可能な例外クラスのいずれとも代入互換性がありません。

興味深いことに、JLS 14.20には次のようにも書かれています。

uni-catch 句では、final として (暗黙的または明示的に) 宣言されていない例外パラメーターは、代入演算子の左側のオペランドとしてスコープ内で発生しない場合、実質的に final と見なされます。

eつまり、 catch ステートメント ( など) を再割り当てしない場合e = new SomeOtherException();、それは暗黙的に final として宣言されます。

したがって、catch ブロックで例外が変更されていない限り、違いはないと結論付けることができます。私が思いつく唯一の例は次のとおりです。

public void method1() throws IOException {
    try {
        throw new IOException();
    } catch (Exception e) { // e is not modified in catch => implicitly final
        throw e; //compiles OK
    }
}

//it works because method1 is semantically equivalent to method2:
public void method2() throws IOException {
    try {
        throw new IOException();
    } catch (final Exception e) {
        throw e;
    }
}

public void method3() throws IOException {
    try {
        throw new IOException("1");
    } catch (Exception e) {
        e = new IOException("2"); //e modified: not implicitly final any more
        throw e; //does not compile
    }
}
于 2012-08-21T09:27:20.707 に答える
2

finalそれを使用できるコードが長すぎて簡単に読んで理解できない場合に役立つと思います。たとえば、可能な限りフィールドを作成finalして、コンストラクターで正しく割り当てられ、クラス内のどこでも変更されないようにします。

a) 値が設定されることが保証されている b) それを使用finalするコードは短くなければならない c) とにかくそれを変更することは非常にまれである.

ただし、それを行うことを妨げるものは何もありません。

于 2012-08-21T09:28:08.583 に答える
0

それがパフォーマンスに関するものかどうかはわかりませんが、慣習に関するものです。Eclipse を使用している場合は、final可能な限りキーワードを追加するフォーマッターを設定し、そのフォーマッターでソース コードを再フォーマットしてみてください。

于 2012-08-21T09:23:37.067 に答える
-1

変更されていないものはすべて最終的なものでなければならないプロジェクトをいくつか見てきました (例: パラメータ、フィールド、ローカル変数など)。

PMDコード アナライザーには対応するスタイル チェックもあり、可能なすべてのものが として宣言されていることを確認しますfinal

于 2012-08-21T09:31:44.277 に答える
-1

例外インスタンスがブロック ローカルであるため、 final が実際にパフォーマンス上の利点をもたらすとは思えません (これはhttps://stackoverflow.com/a/306966/492561を説明する本当に良い答えです)。

したがって、変更しないという明示的なマーカーとして機能するだけです。

場合によっては、例外をスローして戻すように変更する必要がある場合や、メッセージを編集してより高いレベルでより明確にする必要がある場合があります。

基本的には好みの問題だと思いますが、好きな人もいれば嫌いな人もいます。

于 2012-08-21T09:27:50.533 に答える