6

このクエリの目的は、"new" 演算子に関係する Java と C++ の 1 つの側面を比較することです。

これで、C++ でオブジェクトを作成する方法が 2 つあることがわかりました。「new」演算子の有無にかかわらず。その演算子が存在しない場合、領域はヒープ領域に割り当てられませんが、存在する場合、領域はヒープ領域に割り当てられます。

Javaはどうですか?すべてのオブジェクトの作成に「new」演算子が使用されていることに気付きました。配列も「new」演算子で作成されます。Java では、オブジェクトが存在する場所は 1 つしかないということですか?つまり、ヒープ領域ですか?

ありがとう。

4

4 に答える 4

6

はい、 new 演算子は常にヒープ上のオブジェクトにメモリを割り当てます。C++ とは異なり、Java のオブジェクトはスタック上に作成できません。

于 2012-09-16T05:42:54.327 に答える
4

ローカル プリミティブ型とオブジェクト型へのローカル参照は、メソッドにパラメーターとして渡される場合と同様に、どちらも「スタック」メモリを消費します。

すべてのオブジェクト自体は「ヒープ」に相当します。

于 2012-09-16T05:41:07.120 に答える
2

すべての 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 には、オブジェクトが作成されたコンテキストから「エスケープ」するかどうかを判断する実験的な「エスケープ分析」機能があります。エスケープしないオブジェクトは、スタックに安全に割り当てることができます。繰り返しになりますが、この最適化はアプリケーションに対して透過的です。

于 2012-09-16T09:59:12.880 に答える