実際には、実用的な価値がほとんどない同様のトピックがあります。私が理解している限り、プリミティブはパフォーマンスが優れているため、オブジェクト関連の機能 (null
チェックなど) が必要な場合を除いて、あらゆる場所で使用する必要があります。右?
5 に答える
ボクシングが発生するたびに新しいラッパーを作成するのは非常にコストがかかるため、特にメソッドの単一のスコープで通常使用されることを考えると、オートボクシングは共通のラッパーのプールを使用することを忘れないでください。
これは実際にはflyweight デザイン パターンの実装です。既知の値に対してボックス化が発生すると、新しいラッパー インスタンスを作成する代わりに、事前に作成されたインスタンスがプールからフェッチされて返されます。
結果の 1 つは、科学計算にオートボクシングを使用することはまだ推奨されていないことです。たとえば、コード d = a * b + c は、a、b、c、および d に Integer クラスを使用しており、生成されたコードは d.valueOf(a.intValue() * b.intValue() + c.intValue( )))。これらすべてのメソッド呼び出しには独自のオーバーヘッドがあるため、コレクションにプリミティブを格納する必要がある場合は通常、オートボクシングを使用することをお勧めします。
それでも、Integer ラッピング int の膨大なコレクションがある場合、この記事で報告されているように、オーバーヘッドは実行時間が最大20 倍長くなる可能性があります。
Jb は次の重要なコメントを追加します。
また、Wrapper.valueOf(primitive) はラッパーのプールを使用します。したがって、新しい Integer(5) よりも Integer.valueOf(5) を優先してください
プリミティブは、使用する前にボックス化を解除する必要があるため、使用すると高速になります。したがって、VM が実行する追加の手順があります。たとえば、Integer に対して演算を実行するには、演算を実行する前にまず int に変換する必要があります。
多くのビジネス アプリケーションでは、これが問題になることはおそらくほとんどありません。しかし、たとえばグラフィックス変換プロセッサのように非常に数を処理する重いものを作成している場合は、気にする可能性がはるかに高くなります。
はい、プリミティブはオブジェクトよりも高速です。Java 5 以降、手動で変換せずにプリミティブとオブジェクトを混在させることもできます。オートボクシング メカニズムがそれを処理します。
これは、コレクションにプリミティブを配置した場合、コンパイラは文句を言わず、プリミティブを暗黙的にオブジェクトに変換することを意味します。
コレクションにプリミティブを格納する必要がある場合は、commons-primitivesを使用できます。
私はラッパーよりもプリミティブを使用することを好みます。ラッパーが絶対に必要な場所はエンティティクラスだけです。データベースはnullをサポートしているため、エンティティもサポートする必要があります。
私はかつて、データベースアクセスでプリミティブ(および自作ORM)を使用するプロジェクトに取り組んだことがあります。
class Foo{
int xxx = -1;
...
}
そして、あなたは持っていました:
void persist(Foo foo){
...
statement.setInt(15,foo.getXXX()==-1?null:foo.getXXX());
...
}
神それは悪でした。
アプリケーションをプロファイリングし、オートボクシングがパフォーマンスまたはメモリの問題であることがわかった場合にのみ、ラッパーよりもプリミティブを使用することについて心配する必要があります。私の経験では、プリミティブとラッピング オブジェクトについて話すとき、CPU サイクルの前にメモリが問題になります。