15

値渡しと、Java がオブジェクトを割り当てる方法と、オブジェクトをスタックに置くために Java が行うこととの違いを実際に調べていました。

ヒープに割り当てられたオブジェクトにアクセスする方法はありますか? 適切なメソッドがヒープから適切なデータにアクセスできることを保証するために、Java が強制するメカニズムは何ですか?

あなたが狡猾で、実行時に Java バイトコードを操作することさえできれば、想定されていないときにヒープからデータを操作できる可能性がありますか?

4

3 に答える 3

17

JVM命令セットには、ヒープへの任意のアクセスを提供する命令はありません。したがって、バイトコード操作はここでは役に立ちません。

JVMにはベリファイアもあります。(クラスがロードされているときに)すべてのメソッドのコードをチェックして、メソッドがプッシュした値よりも多くの値を実行スタックからポップしようとしないことを確認します。これにより、メソッドは、呼び出し元のメソッドが指すオブジェクトを「見る」ことができなくなります。

最後に、ローカル変数はメソッドごとの配列(「ローカル変数配列」と呼ばれます)に格納されます。この場合も、ベリファイアは、その配列からのすべての読み取り/書き込み命令が、配列のサイズよりも小さいインデックスを指定していることを確認します。これらのJVM命令は、定数インデックスのみを指定できることに注意してください。計算値を取得してインデックスとして使用することはできません。

要約すると、答えは「いいえ」です。

于 2008-11-14T05:01:18.063 に答える
9

Java のすべてのオブジェクトはヒープ上にあります。「ヒープからオブジェクトにアクセスする」という意味がよくわかりません。スタックに保存されるのは、現在のコンテキストとそのローカル変数およびパラメーターを呼び出した関数のリストだけです。すべてのローカル変数とパラメーターは、プリミティブ型または参照のいずれかです。

を使用してオブジェクトを割り当てる場合new(非プリミティブ型を割り当てる唯一の方法です。はい、これには配列型が含まれます)、オブジェクトはヒープに割り当てられ、そのオブジェクトへの参照はスタックまたはヒープに格納されます。 、参照がローカル変数/パラメーターに格納されているか、別のオブジェクトのメンバーとして格納されているかによって異なります。

パラメータとして関数に渡される場合、すべてのオブジェクトは参照によって渡されます。関数がパラメータを変更すると、元のオブジェクトも変更されます。同様に、オブジェクト参照は値渡しであるとも言えます。新しいオブジェクトを参照するようにパラメータを変更すると、関数の実行中はそのオブジェクトを参照し続けますが、渡された元のオブジェクトは以前に参照したものは引き続き参照します。プリミティブ型も値渡しされます。

于 2008-11-14T03:59:38.530 に答える
4

スタック上のオブジェクトに関しては、オブジェクトをスタックに置くことによってバイトコードを最適化しようとするのは、SUN の新しい Java 6 VM (およびおそらく他のいくつか) だけです。通常、すべてのオブジェクトがヒープに入ります。参考までに、 http ://www.ibm.com/developerworks/java/library/j-jtp09275.html をチェックしてください。

また、JVM 仕様はhttp://java.sun.com/docs/books/jvms/second_edition/html/Overview.doc.html#6348にあります。JVM はヒープを破壊するために必要な指示を与えないことでヒープを保護します。JVM 実装の欠陥により、マイレージが異なる場合があります。

于 2008-11-14T05:14:34.290 に答える