すべての Java オブジェクト (つまり、参照を持つすべてのもの) は、アプリケーションとアプリケーション プログラマーの観点からヒープ1に割り当てられます2。Java は、スタック上のオブジェクトの明示的な割り当てをサポートしていません。オブジェクト参照は、ヒープ ノード (つまり、クラスまたはインスタンス フィールド) とスタック フレーム (つまり、ローカル変数など) の両方に格納できます。
実際、キーワードを使用せずに Java でファースト クラスの Java オブジェクトを作成する方法はいくつかあります。new
配列初期化構文は、キーワード{ ... }
なしで配列宣言で使用できます。new
String リテラルには、(クラスのロード時に) String オブジェクトの作成が含まれます。
new
ボックス化変換は、(通常) 明示的な呼び出しまたはメソッド呼び出しなしで新しいラッパー オブジェクトを作成します。
リフレクティブnewInstance
および同様のメソッドは、明示的な なしでオブジェクトを作成しますnew
。
内部では、Java シリアライゼーションの実装はUnsafe
クラス内の特別なメソッドを使用して、宣言されたコンストラクターを実行せずにオブジェクトを作成します。
JNI / JNA API を使用して、ネイティブ コードで Java オブジェクトを作成することもできます。
(最後の 2 つは「Java ではない」という強い議論がありますが、とにかく言及する価値があります。また、文字列リテラルと自動ボクシングのケースには、内部で使用する Java コードが含まれますnew
。)
1 - アプリケーションに対して透過的ですが、複数のヒープが存在する可能性があります。
2 - 最新の Hotspot JVM には、オブジェクトが作成されたコンテキストから「エスケープ」するかどうかを判断する実験的な「エスケープ分析」機能があります。エスケープしないオブジェクトは、スタックに安全に割り当てることができます。繰り返しになりますが、この最適化はアプリケーションに対して透過的です。