2012-01-07 4 views
25

私の質問はかなりシンプルです:
コンパイラは最終クラスのすべてのメソッドを最終的なものとして扱いますか?最終クラスのメソッドにfinalキーワードを追加しても影響はありますか?最終クラスの非最終メソッド

最終的な方法はインライン化の可能性が高いと私は理解しました。これが私が求めている理由です。

ありがとうございます。

答えて

26

あなたが正しいです、最終クラスのすべてのメソッドは暗黙のうちに最終的です。

See here:

「あなたはまた、クラス全体の決勝を宣言することもできます。のような不変クラスを作成する際に が最終的に宣言されたクラスは、 例えば。これは特に便利です、サブクラス化することはできません文字列クラス "

And here:

finalクラスのすべてのメソッドは暗黙のうちに最終的なものです。

また、これはあなたのために興味がある可能性がありますPerformance tips for the Java final keyword

+2

賢明であるには、メソッドが暗黙的に最終的であるかどうかは疑問です。それらを無効にしようとする機会はありません! –

+0

これは、コンパイラがこれらのメソッドを最終として扱うことを意味しますか? (インライン展開)@OliCharlesworth Trueですが、コンパイラが仮想メソッドと最終メソッドをどのように扱うかに違いがあります。 – Acidic

+1

@Acidic:追加したばかりの3番目のリンクを参照してください。おそらく、最終的なことを宣言するためにあなたの道から出る必要はありません。しかし、はい、コンパイラには、それらのメソッドは "最終的"と見なされます。 – EboMike

5

は最終として扱いコンパイラおそれ。

次版画「偽」:

final class FinalClass { 
    public void testMethod() {} 
} 

Method method = FinalClass.class.getDeclaredMethod("testMethod"); 
int m = method.getModifiers(); 
System.out.println(Modifier.isFinal(m)); 
7

コンパイラは、自身最後のものとして、最終的なクラスのすべてのメソッドを処理していますか?

実際はそうです。 finalクラス内のメソッドはオーバーライドできません。メソッドにfinalキーワードを追加(または削除)しても、このルールに違いはありません。

finalクラスのメソッドにfinalキーワードを追加することは効果がありますか?

実際には、それは最小限の効果を有する。オーバーライドに関するルール(上を参照)には効果がなく、インライン展開(下記参照)には影響しません。

実行時にメソッドがfinalキーワードで宣言されているかどうかを知ることができます。リフレクションを使用してメソッドのフラグを確認します。だから、いくつかの効果がありますが、それは99.99%のプログラムと無関係な効果です。

最終的な方法がインライン化の可能性が高いことを理解しました。これが私が求めている理由です。

この理解はが間違っています。現代のJVMのJITコンパイラは、アプリケーションによってがロードされたクラスでどのメソッドがオーバーライドされていないかを追跡します。この情報と静的型を使用して、特定の呼び出しに仮想クラスのディスパッチが必要かどうかを判断します。そうでない場合は、インライン展開が可能であり、メソッド本体の大きさに応じて使用されます。実際には、JITコンパイラはfinalの有無を無視し、より正確なメソッドを使用してメソッドのインライン化が許容されるメソッド呼び出しを検出します。

(事実、これよりも複雑です。アプリケーションは、JITコンパイラのメソッドオーバーライド解析を不正確にするサブクラスを動的に読み込むことができます)この場合、JVMはコンパイルされたメソッドを無効にし、 。再コンパイル)


一番下の行は次のようになります。

  • NOパフォーマンス上の利点がfinalクラスのメソッドにfinalを追加することではありません。

  • ありfinalクラスのメソッドにfinalでパフォーマンス上の利点であるかもしれないが、あなたは古い日JVM、または低品質のJITコンパイラといくつかの他のJava/Javaのようなプラットフォームを使用している場合のみ。あなたは、パフォーマンスを気にしている場合

は、あなたを起こしやすいfinalキーワードであなたのコードベースを汚染するよりも、まともなJITコンパイラで最新/高パフォーマンスのJavaプラットフォームを使用することをお勧めします将来の問題。


あなたはコメントに書いた:私は多くの場所で別々に読んだ

@RussellZahniser。

インターネットには古い情報が多く含まれていますが、その多くは最新ではありません。最初は間違っていませんでした。

+0

ありがとう、それはとても面白いです。この問題に関する正式な情報や何らかの決定的なテストと結果はありますか? – Acidic

+0

また、私が以前に尋ねた関連する質問では、 'final'メソッドが実際にインライン化される可能性が高いことを理解するように導かれています:http:// stackoverflow。com/questions/8639704/getter-and-setters-get-in-the-compilerコンパイラ – Acidic

+1

@Acidic - 私の理解は、 'final'は何の違いもなく、私はこれと矛盾する真の証拠がないことを知っている。決定的な答えが本当に必要な場合は、OpenJDKのソースコードを見て、JITコンパイラが実際に何をしているのかを見てください。 –

関連する問題