4

これは解決策の質問というよりは理論の質問ですので、聞いてください。

C / C ++およびPHPでは、定数を宣言できます。通常、これを行うにはいくつかの方法があり(#DEFINEたとえば、または' const type' ...)、これの最終的な効果は、コンパイル中に、これらの名前付き定数がすべてリテラルになるように置換が行われることです。これは、データを見つけるためにメモリの場所にアクセスする代わりに、データがハードコーディングされるために役立ちますが、ハードコーディングの欠点はありません-再利用する必要がある場合は値を呼び出し、その値のすべてのインスタンスを変更する変更する必要があります。

しかし、Javaのfinal宣言は少し不可解です。最終変数が設定されていないクラスを作成し、構築時に初期化できるため、私が知る限り、それらはリテラルとしてプリコンパイルされていないことを意味します。口内炎の構造を論理的に変更できないことを保証する以外に、final宣言は効率に何らかの利益をもたらしますか?

final記事への参照は、実際に何をするのか、そして建設後に価値の変化を止める以外の利点がある場合はどうなるのかを説明する部分に注意する限り、問題ありません。

当然の結果として、Javaでコンパイルレベルの定数を、単にリテラルを使用する以外の方法で実際に宣言することは可能ですか(とにかく悪い考えですか?)

4

4 に答える 4

5

Java には定数式があります。Java言語仕様のこちらを参照してください。

A compile-time constant expression is an expression denoting a value of primitive type or a String that does not complete abruptly and is composed using only the following:

Literals of primitive type and literals of type String (§3.10.5)
Casts to primitive types and casts to type String
The unary operators +, -, ~, and ! (but not ++ or --)
The multiplicative operators *, /, and %
The additive operators + and -
The shift operators <<, >>, and >>>
The relational operators <, <=, >, and >= (but not instanceof)
The equality operators == and !=
The bitwise and logical operators &, ^, and |
The conditional-and operator && and the conditional-or operator ||
The ternary conditional operator ? :
Parenthesized expressions whose contained expression is a constant expression.
Simple names that refer to constant variables (§4.12.4).
Qualified names of the form TypeName . Identifier that refer to constant variables (§4.12.4).

しかし、Java では、C/C++ とは異なり、JIT コンパイラも使用できるため、追加のインライン展開が可能です。つまり、実際のパフォーマンスの問題が発生するまで心配する必要はありません。

于 2012-09-12T15:27:07.037 に答える
4

Java には、コンパイル時に Java コンパイラが値に置き換える定数があります。たとえば、タイプのメンバー変数とfinalタイプのメンバー変数は、String事実上、この方法で置き換えられる定数です。String(クラスは不変であるため、これは許可されています)。この結果の 1 つは、ソース コードで文字列を変更しても、この文字列が使用されているクラスを再コンパイルしない場合、それらのクラスは文字列の新しい値を認識しないということです。

JLS は、次の段落でこれを説明しています。

4.12.4final変数

13.4.9finalフィールドと定数

于 2012-09-12T15:37:23.460 に答える
2

final フィールドは、不変オブジェクトを作成することを目的としています。

static final フィールドは、一種の定数です。

コンパイラーの最適化、データフロー分析は、ある程度行われます。javap を試して、jvm バイト コードを確認してください。

于 2012-09-12T15:38:57.620 に答える
1

最終宣言は効率に何らかの利益をもたらしますか?

あまり。これは、多くの場合、JIT が実行時に値が変更されていないと判断し、それを最終的なものとして扱うことができるためです。(値が揮発性ではなく、別のスレッドで変更された場合、これは問題です)

Java 8 では、ローカル変数を final として宣言するのではなく、final にすることができれば、クロージャでローカル変数を使用できます。

于 2012-09-12T15:39:58.217 に答える