11

nullC および C++での逆参照によって、未定義の結果が生じる場合があることを知りました。これは、すべての奇妙なプログラミング動作と同様に、私にとって非常に興味深いものです (私はかつて、正規の運用環境で「破損した RAM - プログラムが書かれたとおりに実行されない」をデバッグしたと誰かに言われました)。私は主に Java 開発者なので、Java 言語でも同様のことが起こる可能性があるのではないかと考えていました。

JLS はnullリファレンスの実装方法 ( 3.10.74.115.8.1 ) について具体的ではないため、よくわかりません。でもUnsafe APIでメモリアドレスを直接操作することで可能になるのではないかと考えていました。残念ながら、これが可能かどうかを判断するには、JVM の内部動作について十分な知識がありません。

可能であれば、悪意のあるプログラムも同様にそうする可能性があり、興味深いセキュリティ上の懸念が生じます

nullでは、単に をスローするのではなく、を逆参照するときに Java が未定義の動作をする可能性はありNullPointerExceptionますか?

4

4 に答える 4

1

未定義の動作を持つ言語機能の概念そのものは、C および C++ 標準の作成者が、標準が特定の動作を必要としないことを明確にするために使用するものです。これにより、C および C++ のさまざまな実装者が、実装対象の特定のハードウェアまたはオペレーティング システムにとって最も効率的または便利なことを行うことができます。これは、C が常に移植性よりもパフォーマンスを優先しているためです。しかし、Java には反対の優先順位があります。その初期のスローガンは「一度書けば、どこでも実行できる」でした。そのため、Java 言語仕様は未定義の動作については言及しておらず、すべての言語機能の動作を定義するよう努めています。

null 参照を使用すると、状況によっては何らかの形でメモリが破損する可能性があると考えているようです。C/C++ ポインタと Java 参照を混同していると思います。ポインタは基本的にメモリ アドレスです。ポインタを にキャストしてvoid *逆参照することにより、メモリの内容を無制限に破壊することができます。Java 参照はメモリ アドレスとは異なります。これは、ガベージ コレクタがオブジェクトをメモリ内の別の場所に自由に移動できる必要があるためですしたがって、Java 参照のメモリ アドレスへの変換は、JVM だけが行うことができます。Java プログラム自体ができることではありません。この変換は JVM によって完全に制御されるため、JVM は変換が常に有効であり、常に本来あるべきオブジェクトを指し、それ以外の場所を指さないことを保証できます。

于 2013-10-23T07:34:52.167 に答える