次の表に、プリミティブ型とそのオブジェクト ラッパー クラスを示します。
カプセル化されたクラス | |
ブール値 | |
#文字 | |
バイト | |
Short | |
Integer | |
long # Long | |
Float | |
Double |
int i = 5; // 原始类型 Integer j = new Integer(10); // 对象引用
両方の変数がローカル変数テーブルに格納されます。 , そして、それらはすべて Java オペランド スタック上で動作しますが、その表現はまったく異なります。 (この記事の残りの部分では、オペランド スタックやローカル変数テーブルの代わりにスタックという一般的な用語が使用されます。) プリミティブ型 int とオブジェクト参照は、それぞれスタックの 32 ビットを占有します。 (int またはオブジェクト参照を表すには、Java 仮想マシンの実装には少なくとも 32 ビットのストレージが必要です。) Integer オブジェクトのスタック エントリは、オブジェクト自体ではなく、オブジェクト参照です。
Java のすべてのオブジェクトは、オブジェクト参照を通じてアクセスされます。オブジェクト参照は、オブジェクトが格納されているヒープ内の領域へのポインタです。プリミティブ型を宣言すると、その型自体のストレージを宣言することになります。
参照型とプリミティブ型には異なる特性と使用法があり、サイズと速度の問題、参照型とプリミティブ型が特定のクラスの参照として使用される場合に、この型がどのデータ構造に格納されるかなどの問題が含まれます。インスタンスデータを使用する場合に指定されるデフォルト値。オブジェクト参照インスタンス変数のデフォルト値は null ですが、プリミティブ型インスタンス変数のデフォルト値はその型によって異なります。
多くのプログラムのコードには、プリミティブ型とそのオブジェクト ラッパーの両方が含まれます。両方のタイプを操作し、それらがどのように相互作用して共存するかを正しく理解することは、それらが等しいかどうかをチェックするときに問題になります。プログラマーは、コード内のエラーを避けるために、これら 2 つのタイプがどのように機能し、相互作用するかを理解する必要があります。
たとえば、プリミティブ型のメソッドを呼び出すことはできませんが、オブジェクトのメソッドを呼び出すことはできます。
int j = 5; j.hashCode(); // 错误 //。.. Integer i = new Integer(5); i.hashCode(); // 正确
プリミティブ型を使用するには、新しいオブジェクトを呼び出したり、オブジェクトを作成したりする必要はありません。これにより、時間とスペースが節約されます。プリミティブ型とオブジェクトを混合すると、代入に関連して予期しない結果が生じる可能性があります。バグがないように見えるコードでも、意図した動作を実行できない可能性があります。例:
import java.awt.Point; class Assign { public static void main(String args[]) { int a = 1; int b = 2; Point x = new Point(0,0); Point y = new Point(1,1); //1 System.out.println(“a is ” + a); System.out.println(“b is ” + b); System.out.println(“x is ” + x); System.out.println(“y is ” + y); System.out.println(“Performing assignment and ” + “setLocation.。.”); a = b; a++; x = y; //2 x.setLocation(5,5); //3 System.out.println(“a is ”+a); System.out.println(“b is ”+b); System.out.println(“x is ”+x); System.out.println(“y is ”+y); } }
このコードは次の出力を生成します:
a is 1 b is 2 x is java.awt.Point[x=0,y=0] y is java.awt.Point[x=1,y=1] Performing assignment and setLocation.。. a is 3 b is 2 x is java.awt.Point[x=5,y=5] y is java.awt.Point[x=5,y=5]
整数 a と b を変更した結果には驚くべきことはありません。 b の値が整変数 a に代入され、a の値が 1 増加します。この出力は、私たちが望んでいることを反映しています。ただし、驚くべきことは、setLocation を割り当てて呼び出した後の x オブジェクトと y オブジェクトの出力です。特に、x = y の代入が完了した後、x で setLocation を呼び出しましたが、x と y の値が同じになるのはなぜでしょうか?結局のところ、y を x に代入してから x を変更しました。これは整数 a と b で行ったことと何ら変わりません。
この混乱は、プリミティブ型とオブジェクトの使用によって引き起こされます。割り当ては 2 つのタイプで同様に機能します。しかし、それはすべて違って見えるかもしれません。代入により、等号 (=) の左側の値が右側の値と等しくなります。これは、前述の int a や b などのプリミティブ型では明らかです。非プリミティブ型 (Point オブジェクトなど) の場合、代入によってオブジェクト自体ではなくオブジェクト参照が変更されます。したがって、ステートメント
x = y;
の後では、x は y と等しくなります。つまり、x と y はオブジェクト参照であるため、同じオブジェクトを参照することになります。したがって、x を変更すると y も変更されます。 //1 のコード実行後の状況は次のとおりです。
//2 の代入実行後の状況は次のとおりです。
//3 で setLocation が呼び出されたときの場合、このメソッドは x で参照されるオブジェクトに対して実行されます。 x によって参照される Point オブジェクトは y によって参照されるオブジェクトでもあるため、次の結果が得られます。
x と y は同じオブジェクトを参照するため、x で実行されるすべてのメソッドは、x で実行されるメソッドと同じです。 y すべてが同じオブジェクトに作用します。
参照型とプリミティブ型を区別し、参照のセマンティクスを理解することが重要です。これを行わないと、作成されたコードが本来の役割を果たせなくなります。
以上がJavaの参照型とプリミティブ型の違いは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。