4

私のJavaクラス

private static final String constantString = "Constant";    
private static final Integer constantInteger = 5;
public static void main(String[] args) {
    String s2 = constantString + "append"; // LINENUMBER 9
    Integer i2 = constantInteger + 7; // LINENUMBER 10
}

バイトコード

 LINENUMBER 9 L0
    LDC "Constantappend"
    ASTORE 1
   L1
    LINENUMBER 10 L1
    GETSTATIC TestClass.constantInteger : Ljava/lang/Integer;
    INVOKEVIRTUAL java/lang/Integer.intValue()I
    BIPUSH 7
    IADD

質問1:コンパイラが最終的な整数(constantInteger)値を5に置き換えないのはなぜですか?しかし、文字列の場合は置き換えました!

整数変数の最後のキーワードを削除する場合

Javaコード:

private static Integer constantInteger = 5;

バイトコード:

LINENUMBER 10 L1
GETSTATIC TestClass.constantInteger : Ljava/lang/Integer;
INVOKEVIRTUAL java/lang/Integer.intValue()I
BIPUSH 7

バイトコードは、2つの異なる場合(static final Integer、static Integer)で同じです。

質問2:では、整数をfinalにすることの使用法は何ですか?

4

4 に答える 4

6

推測:理由は文字列のインターンです。コンパイラは文字列をインターンし、インターンされた文字列の連結を最適化します。しかし、それはNumbersをインターンせず、明らかに最適化を欠いています。

コンパイラに実装されていないことを除けば、整数の場合を最適化できなかった理由は考えられません。他の回答で述べたように、Integer +には、string +とその暗黙のStringBuilder最適化およびインターンロジックとはまったく異なる、ボックス化/ボックス化解除操作が含まれます。したがって、文字列+最適化は、コンパイラの実装の観点から「無料」で提供される可能性があります。

于 2012-11-17T14:23:13.593 に答える
5

コンパイラーは、null以外の値を持つ最後の整数が必然的にnullでないことに気付くことはありません。それで、それは先に進んで、それを箱から出します。JITコンパイラがコードをマシン化する途中でこれを改善する可能性は十分にあります。どちらの方法でも、これがアプリケーションのパフォーマンスにとって実際の問題になる可能性はほとんどありません。

「最終」は、パフォーマンスではなく、セマンティクスに関するものです。言語はセマンティクスを保証します。パフォーマンスは完全に実装者の気まぐれです。したがって、「質問#2」に明示的に答えるには、最終的なポイントは、変更を防ぐセマンティクスを持つことです。また、埋め込み匿名クラスのルールにも注意してください。これらのクラスでは、最終的なローカル変数のみを使用できます。

于 2012-11-17T14:20:25.750 に答える
3

簡単な答え:試してみてくださいstatic final int constantInteger = 5

コンパイラは定数式のみを置き換えることができます。Javaには、いわゆるプリミティブ値があります。これは、小文字で始まる型(long、int、char、...)です。これらの値はオブジェクトではないため、状態を設定することはできず、直接置き換えることができます。

最適化として、Stringオブジェクトはコンパイラーによって定数のように扱うこともできます。実行時には、文字列は文字配列を保持する単なるコンテナですが、コンパイル時には、コンパイラは文字列が単なる文字データであると偽ります。ただし、Stringこの例外が発生したクラスはこれだけです。

同様の理由で、とを使用できますがStringClass注釈の値に他のオブジェクトタイプを使用することはできません。

于 2012-11-17T14:17:56.860 に答える
1

Java言語仕様、v3から:

定数式(§15.28)によって計算された文字列は、コンパイル時に計算され、リテラルであるかのように扱われます。

2つのリテラルで構成される文字列式は、コンパイル時に1つのリテラルに計算されます。整数はそのような扱いを受けません。

于 2012-11-17T14:32:21.863 に答える