オブジェクトをラップする代わりにプリミティブを使用する必要があるのはいつですか?

StackOverflow https://stackoverflow.com/questions/239560

質問

実際にはこちらは、実用的な価値がほとんどない同様のトピックです。 私が理解する限り、プリミティブはパフォーマンスが向上しており、オブジェクト関連機能(例: null チェック)が必要な場合を除き、あらゆる場所で使用する必要があります。そうですか

役に立ちましたか?

解決

すべてのボクシングオカレンスに対して新しいラッパーを作成するのは非常に費用がかかるため、特にメソッドの単一のスコープで通常使用されることを考慮すると、オートボクシングは、一般的なラッパーのプールを使用します。

これは、実際にはフライウェイトデザインパターン。既知の値に対してボクシングが発生すると、新しいラッパーインスタンスを作成する代わりに、事前に作成されたインスタンスがプールからフェッチされて返されます。

結果として、科学計算にオートボクシングを使用することはまだお勧めできません。たとえば、コードd = a * b + cは、a、b、c、およびdに整数クラスを使用しており、生成されるコードはd.valueOf(a.intValue()* b.intValue()+ c.intValue( ))。これらのメソッド呼び出しにはすべて独自のオーバーヘッドがあるため、コレクションにプリミティブを格納する必要がある場合は、オートボクシングを使用することを通常お勧めします

そして、それでも、整数のラッピング整数の巨大なコレクションがある場合、オーバーヘッドは20倍までの実行時間を意味します。 = "http://www.javaspecialists.co.za/archive/Issue090.html" rel = "nofollow noreferrer">この記事で報告。


Jbは次の重要なコメントを追加します:

  

また、Wrapper.valueOf(primitive)はラッパーのプールを使用します。したがって、新しいInteger(5)よりもInteger.valueOf(5)を優先します

他のヒント

プリミティブは、使用する前にボックス化を解除する必要があるため、使用すると高速になります。したがって、VMが実行する追加のステップがあります。たとえば、整数で算術演算を実行するには、算術演算を実行する前にまず整数に変換する必要があります。

多くのビジネスアプリケーションでは、これはおそらくほとんど問題になりません。しかし、たとえばグラフィック変換プロセッサのような非常に多くの重いものを書いている場合、あなたは気にする可能性が非常に高くなります。

はい、プリミティブはオブジェクトよりも高速です。 Java 5以降では、プリミティブとオブジェクトを手動で変換することなく混在させることもできます。 オートボクシングメカニズムがそれを処理します。

これは、コレクションにプリミティブを配置した場合、コンパイラは文句を言わず、プリミティブをオブジェクトに暗黙的に変換することを意味します。

コレクションにプリミティブを保存する必要がある場合は、 commons-primitives を使用できます。

ラッパーにプリミティブを使用することを好みます。ラッパーが絶対に必要なのはエンティティクラスのみです。データベースはヌルをサポートしているため、エンティティも必要です。

データベースアクセスでプリミティブ(およびhomebrew ORM)を使用したプロジェクトに取り組んだことがあります:

 class Foo{
    int xxx = -1;
 ...
 }

そして、あなたは次のようになりました:

 void persist(Foo foo){
     ...
     statement.setInt(15,foo.getXXX()==-1?null:foo.getXXX());
     ...
}

神は悪でした。

アプリケーションのプロファイルを作成し、オートボクシングがパフォーマンスまたはメモリの問題であることを確認した場合にのみ、ラッパーでプリミティブを使用することについて心配する必要があると思います。私の経験では、プリミティブとオブジェクトのラップについて話すとき、CPUサイクルの前にメモリが問題になります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top