Cにはポインターがあり、Javaには参照と呼ばれるものがあります。それらはすべてが何かを指しているという意味でいくつかの共通点があります。Cのポインターはそれらが指すアドレスを格納することを知っています。参照はアドレスも保存しますか?ポインターがより柔軟でエラーが発生しやすいという点を除いて、それらはどのように異なりますか?
アドレスを格納することで参照が実装される場合があります。通常Java参照はポインタとして実装されますが、必須ではありません仕様によります。ガベージコレクションを容易にするために、間接的な追加のレイヤーを使用している可能性があります。ただし、最終的には(ほとんどの場合)(Javaスタイル)参照の実装に関与している(Cスタイル)ポインターに要約されます。 。
参照を使用してポインター演算を実行することはできません。 CのポインターとJavaの参照との最も重要な違いは、実際には到達できないことです(および操作)Javaでの参照の基礎となる値言い換えると、ポインタ演算を行うことはできません。
Cでは、ポインタ(つまりアドレス)に何かを追加したり、「近く」にあるものをポイントしたり、任意の場所にある場所をポイントしたりすることができます。
Javaでは、参照は1つのことだけを指します。変数にdifferent参照を保持させることはできますが、「元のものの後にあるもの」を指すように要求することはできません。
参照は強く型付けされています。もう1つの違いは、参照の型がより多くより厳密に制御されていることですJavaよりもポインタのタイプはCです。Cでは、int*
を使用してchar*
にキャストし、その場所のメモリを再解釈することができます。この再解釈は、 Java:参照の反対側にあるオブジェクトは、それがすでにであるものとして解釈できます(つまり、Object
参照をString
参照が指すオブジェクトが実際にString
の場合のみ)。
これらの違いにより、Cポインターはより強力になりますが、より危険になります。これらの両方の可能性(ポインター演算と、ポイントされている値の再解釈)により、Cに柔軟性が追加され、いくつかの機能のソースになります。言語の。しかし、これらはまた問題の大きな原因です。なぜなら、誤って使用すると、コードが構築されているという仮定を簡単に破ることができるからです。そして、それらを誤って使用するのはかなり簡単です。
C++参照は再び異なります。
それらは初期化する必要があり、nullにすることはできません(少なくとも整形式のプログラムでは)、他の何かを参照するために再装着することはできません。 C++参照は、オブジェクトのエイリアスにはるかに似ています。
ポインタとJava/C++参照のもう1つの重要な違いは、参照のアドレスにアクセスできないポインタのアドレスを取得できることです(実際、C++参照は実際にはメモリ内のオブジェクトとしてまったく存在する必要はありません)。参照への参照ではなく、ポインタへのポインタ
Java参照とCポインタは、正確に2つの点で異なります。
char
、int
などの基本的な型は絶対に参照しません)。コンパイラがint*
をchar*
として処理するように強制できないため、参照が強く型付けされていると誰かが書いています。
特定の変換が実際には安全であるという事実を除けば、Cにはポリモーフィズムがないため、比較は重要ではありません。
確かに、JavaはCよりも強く型付けされていますが、これはCポインタの機能ではありません= Java参照、使用する必要があります(一般的な制限を無視することを除いて)タイプセーフを破るJNIですが、Cでもコンパイラを強制する必要があります。
Java参照はCポインタとして実装されている可能性があります。確かに、それらは厳密にはそれほど強力ではないため、32ビットマシンでは、JVMがCで実装されている場合はそうです。64ビットマシンでも、スペースと帯域幅を節約するために、通常は 圧縮された通常のオブジェクトポインター ( "圧縮されたOOP")です。
とにかく、それらのCポインタは、パフォーマンス上の理由で通常(実装の99%以上)であっても、ハードウェアアドレスと同等である必要はありません。
最後に、これはプログラマーに公開されていない実装の詳細です。