2012-10-05 19 views
5

Javaで静的最終定数が本当に必要ですか?定数値を返すメソッドの使用

は、私は次のコードがあるとします。

public class Test { 

    public static final int A = 1234; 

    public static int getA() 
    { 
     return 1234; 
    } 
} 

あなたは、効率の面で以下の2つの場合を比較していただけますか?効率の点で

  1. Test.A

  2. Test.getA()

+0

http://codebetter.com/raymondlewallen/2005/07/19/4-major-principles-of-object-oriented-programming/ – talnicolas

+0

私は、バイトコードが出てくるものが不思議です。 'static final'変数を返す' static'メソッドは非常に最適化可能です。 – Brian

答えて

9

JITコンパイラを想定すると、少なくともアプリケーションの実行速度に大きな違いを生じさせるほどの効率の違いはありません。

柔軟性には目立つ利得がありますが、値を後で計算する方法を変更できるため、メソッドに値をカプセル化することはほぼ常に有効です。

このルールの例外は、数学の世界からの純粋な定数です。この基本定数の値が変更される可能性がないため、Math.PIへのアクセスをカプセル化することはあまり意味がありませんプログラムで値が取得されたメソッドを切り替える必要があります。

+0

+1フレキシブルな利益のためだと思う。 – Gamb

+0

Math.PI良い例 – Jayy

+1

特に、定数への参照はそれらを使用するコードにそのままコピーされるので、定数が変更された場合は、定数を使用するコードをすべて再コンパイルして新しい値を取得する必要があります。 –

1

test.getA()はしばしばJITによってtest.A相当に減少させることができます。それでも、その違いはせいぜい無視できるだけです。

Javaで静的最終定数が本当に必要ですか?

いいえ、繰り返し割り当てを防止するのに役立ちます。

+0

JITはこれを実際に最適化しますが、これは[エスケープ解析](http://docs.oracle.com/javase/7/docs/technotes/guides/vm/performance-enhancements-7.html#escapeAnalysis)ではありません。 – Jesper

+0

@ジェスパー、トピックの私の記憶をリフレッシュした後、私はあなたが右の –

0

あなたが表示するケースは、私が意図していると思うかなり簡単です。あなたの最初のケースは、スタック上のコールが少なくて済むので、より直接的かつ効率的ですが、より良いコーディングスタイルは2つを組み合わせることだと思います。私はこれがあなたのクラスでこの変数を使用する唯一の場所ではないと考えています。

public class Test { 

public static final int A = 1234; 

public static int getA() 
{ 
    return A; 
} 

public static int doSomething() 
{ 
    int result = A * 10; 
    //do more stuff 
    return result; 
} 
} 

これは、あなたが唯一、それは常に変化する必要がある場合、一つの場所にあなたの変数を変更し、プログラム全体で期待される結果を取得することができます。個人的には、クラスをどのように設定する必要があるのか​​を知るために、intメソッドをprivateメソッドにするだけです。このようにして、変数名の後ろに '()'が必要なのか、クラス外にあるすべての変数に同じ方法でアクセスするのかを覚えていない問題は決して起こりません。これのほとんどは、コーディングスタイルであり、正解でも間違いでもありません。

1

静的最終変数は外部コードでは変更できないため、カプセル化する必要はありません。

また、パラメータを持たない静的メソッドは、静的メソッドであるため、オブジェクトの状態へのアクセスを示唆しています。

コンパイラ側では、効率の点で大きな違いはないはずですが、プログラムの読みやすさと自己文書化コードに関して、静的なfinalはより良い、時間のテストされたオプションです。

2

staticfinal定数は、メソッドから返されるリテラル値とは異なる動作をします。 Javaコンパイラは、コンパイル時にでこれらを使用します()。

一例として、最初のケースで

public static boolean DEBUG = false; 

... 

if (DEBUG) 
{ 
    ...do something... 
} 

public boolean debug() 
{ 
    return false; 
} 

... 

if (debug()) 
{ 
    ...do something 2... 
} 

、条件と...は、何かをする...コードはコンパイルされたバイトコードには含まれません(クラスファイル)。 2番目のケースでは、条件と... 2つのコードが含まれますが実行されることはありません。実行時にコードを削除するにもかかわらず、この場合、JITは十分な分析を行います。

Javaの初期段階では、JITは存在しないか、文字通りの値を返す単純なメソッドを最適化するほどスマートではありませんでした。その後、パフォーマンスのために一定の値が必要でした。コンパイル時に外部クラス(public/protected静的最終定数用)がそのバイトコードに焼き付けられた値を持つことを覚えている場合は、このように定数を定義する方が便利です。実行時にソースクラスから値を取得するのではなく、