33

最近、次のようなコード (Java) を見ました。

myMethod(new Integer(123));

現在、いくつかのコードをリファクタリングしています。Sonar ツールには、次のように sth を使用する方がメモリにやさしいというヒントがあります。

myMethod(Integer.valueOf(123));

ただし、この場合、次を使用しても違いはないと思います。

myMethod(123);

メソッドに変数を渡すと理解できましたが、ハードコードされた int? または、Long/Double などがあり、数値の Long 表現が必要な場合。でも整数?

4

5 に答える 5

40

new Integer(123)Object呼び出しごとに新しいインスタンスを作成します。

javadocによると、Integer.valueOf(123)オブジェクトをキャッシュするという違いがあります...そのため、Object複数回呼び出すと同じ結果になる場合があります(またはない場合があります)。

たとえば、次のコード:

   public static void main(String[] args) {

        Integer a = new Integer(1);
        Integer b = new Integer(1);

        System.out.println("a==b? " + (a==b));

        Integer c = Integer.valueOf(1);
        Integer d = Integer.valueOf(1);

        System.out.println("c==d? " + (c==d));

    }

次の出力があります。

a==b? false
c==d? true

値の使用に関してintは、プリミティブ型を使用しています (メソッドもその署名でプリミティブ型を使用していることを考慮してください) - 使用するメモリがわずかに少なくなり、高速になる可能性がありますが、コレクションに追加することはできません。例えば。

また、メソッドのシグネチャで Java のAutoBoxingIntegerが使用されている場合は、Java の AutoBoxing も参照してください。これを使用すると、JVM が自動的に呼び出しInteger.valueOf()ます (したがって、キャッシュも使用します)。

于 2012-01-27T08:52:33.593 に答える
9

public static Integer valueOf(int i)

指定された int 値を表す Integer インスタンスを返します。新しい Integer インスタンスが必要ない場合は、コンストラクター Integer(int) よりもこのメソッドを優先して使用する必要があります。このメソッドは、頻繁に要求される値をキャッシュすることによって、空間と時間のパフォーマンスが大幅に向上する可能性が高いためです。

パラメータ:
i- int 値。
戻り値:
aを表す整数インスタンスi
以降:
1.5

http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Integer.html#valueOf%28int%29を参照してください

valueOf のこのバリアントは、JDK 5 で Byte、Short、Integer、および Long に追加されました (これは、JDK 1.4 以降、Boolean の単純なケースで既に存在していました)。もちろん、これらはすべて Java の不変オブジェクトです。以前は、int から Integer オブジェクトが必要な場合は、新しい Integer を構築していました。しかし、JDK 5 以降では、実際に valueOf を使用する必要があります。これは、Integer が -128 から 127 の間の Integer オブジェクトをキャッシュし、まったく同じ Integer(0) オブジェクトをまったく新しいオブジェクトで構築するのを無駄にする代わりに、毎回同じ正確な Integer(0) オブジェクトを返すことができるためです。 .

private static class IntegerCache {
private IntegerCache(){}

static final Integer cache[] = new Integer[-(-128) + 127 + 1];

static {
    for(int i = 0; i < cache.length; i++)
    cache[i] = new Integer(i - 128);
}
}

public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
    return IntegerCache.cache[i + offset];
}
    return new Integer(i);
}

Integer.valueOf(int) を使用する理由を参照してください

編集

オートボクシングとオブジェクト作成:

考慮しなければならない重要な点は、オートボクシングはオブジェクトの作成を減らすのではなく、コードの複雑さを減らすということです。経験則として、オブジェクトを必要としないプリミティブ型を使用することをお勧めします。これには次の 2 つの理由があります。

プリミティブ型は、対応するラッパー型よりも遅くはなく、はるかに高速になる可能性があります。== (参照の比較) と .equals() (値の比較) に関連する予期しない動作が発生する可能性があります。

通常、プリミティブ型がラッパー型にボックス化されると、JVM はメモリを割り当て、新しいオブジェクトを作成します。ただし、一部の特殊なケースでは、JVM は同じオブジェクトを再利用します。

以下は、不変オブジェクトとして格納されるプリミティブのリストです。

  • ブール値 true および false

  • すべてのバイト値

  • -128 から 127 までの短い値

  • -128 ~ 127 の int 値

  • \u0000 から \u007F の範囲の文字

http://today.java.net/pub/a/today/2005/03/24/autoboxing.html#performance_issueを参照

于 2012-01-27T08:54:15.260 に答える
1

int はプリミティブ型であり、オブジェクトではありません。

new Integer(123)どちらも値 123 を表すオブジェクトを返しInteger.valueOf(123)ます。IntegerInteger.valueOf()

指定された int 値を表す Integer インスタンスを返します。新しい Integer インスタンスが必要ない場合は、コンストラクター Integer(int) よりもこのメソッドを優先して使用する必要があります。このメソッドは、頻繁に要求される値をキャッシュすることによって、空間と時間のパフォーマンスが大幅に向上する可能性が高いためです。

于 2012-01-27T08:56:03.360 に答える
1

メソッドには または が必要intですIntegerか?

new Integer(int)Integer.valueOf(int)どちらもIntegerオブジェクトを返しますが、valueOfキャッシュされたオブジェクトを返すため、より効率的であるため、優先する必要があります。メソッドに が必要な場合は、Integerを使用する必要がありますInteger.valueOf

メソッドに が必要な場合は、 (例: )intを使用する必要があります。int123

ただし、この方法で型を一致させる必要は厳密にはありません。これは、型が一致しない場合に を自動的にから へ、またはその逆に変換するautoboxingがあるためです。これにより、 を必要とするメソッドに を、 を必要とするメソッドに を渡すことができます。ただし、オートボクシングに関連するパフォーマンス コストがあることに注意してください。オートボクシングを使用する最も一般的な例は、プリミティブをコレクションに格納する場合です。intIntegerintIntegerIntegerint

于 2012-01-27T09:08:50.423 に答える
1

-128 から +127 の範囲のみがキャッシュに実装されます。

Integer a = new Integer(1);
 Integer b = new Integer(1);

 System.out.println("a==b? " + (a==b));

 Integer c = Integer.valueOf(127);
 Integer d = Integer.valueOf(127);

 System.out.println("c==d? " + (c==d)); 

 Integer e = Integer.valueOf(128);
 Integer f = Integer.valueOf(128);

 System.out.println("e==f? " + (e==f)); 

この Java 仕様を参照してください。

http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.7

JDK 5+ では、実際には valueOf を使用する必要があります。これは、Integer が -128 から 127 の間の Integer オブジェクトをキャッシュし、まったく同じ Integer(0) オブジェクトを毎回返すことができるためです。

于 2012-01-27T09:18:35.983 に答える