Javaのボックス化とアンボックス化の詳細な説明とサンプルコード
Java のボックス化とアンボックス化の詳細な説明
前書き:
ボックス化とアンボックス化の概念を理解するには、Java データ型を理解する必要があります
ボックス化: 基本型を対応する参照型でラップして、オブジェクトの性質を持たせる。 Int は Integer にパッケージ化され、float は Float にパッケージ化されます
Unboxing: ボックス化とは逆に、参照型オブジェクトは値型 data に単純化されます
Integer a = 100; 这是自动装箱 (编译器调用的是static Integer valueOf(int i)) int b = new Integer(100); 这是自动拆箱
次のコード部分を見てください
m1
public class DataType { public static void main(String args[]) { DataType dt = new DataType(); dt.m11(); dt.m12(); } public void m11() { Integer a = new Integer(100); Integer b = 100; System.out.println("m11 result " + (a == b)); } public void m12() { Integer a = new Integer(128); Integer b = 128; System.out.println("m12 result " + (a == b)); } }
印刷結果は?
m11 result false m12 result false
"== はアドレスを比較し、2 つのオブジェクト a と b のアドレスは異なります。つまり、これらは 2 つのオブジェクトであるため、どちらも false です
javap を通じてバイトコードを解析します。内容は次のとおりです
public void m11(); Code: 0: new #44; //class java/lang/Integer 3: dup 4: bipush 100 6: invokespecial #46; //Method java/lang/Integer."<init>":(I)V 9: astore_1 10: bipush 100 12: invokestatic #49; //Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 15: astore_2 16: getstatic #53; //Field java/lang/System.out:Ljava/io/PrintStream; 19: new #59; //class java/lang/StringBuilder 22: dup 23: ldc #61; //String m11 result 25: invokespecial #63; //Method java/lang/StringBuilder."<init>":(Ljava/la ng/String;)V 28: aload_1 29: aload_2 30: if_acmpne 37 33: iconst_1 34: goto 38 37: iconst_0 38: invokevirtual #66; //Method java/lang/StringBuilder.append:(Z)Ljava/la ng/StringBuilder; 41: invokevirtual #70; //Method java/lang/StringBuilder.toString:()Ljava/l ang/String; 44: invokevirtual #74; //Method java/io/PrintStream.println:(Ljava/lang/St ring;)V 47: return public void m12(); Code: 0: new #44; //class java/lang/Integer 3: dup 4: sipush 128 7: invokespecial #46; //Method java/lang/Integer."<init>":(I)V 10: astore_1 11: sipush 128 14: invokestatic #49; //Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 17: astore_2 18: getstatic #53; //Field java/lang/System.out:Ljava/io/PrintStream; 21: new #59; //class java/lang/StringBuilder 24: dup 25: ldc #82; //String m12 result 27: invokespecial #63; //Method java/lang/StringBuilder."<init>":(Ljava/la ng/String;)V 30: aload_1 31: aload_2 32: if_acmpne 39 35: iconst_1 36: goto 40 39: iconst_0 40: invokevirtual #66; //Method java/lang/StringBuilder.append:(Z)Ljava/la ng/StringBuilder; 43: invokevirtual #70; //Method java/lang/StringBuilder.toString:()Ljava/l ang/String; 46: invokevirtual #74; //Method java/io/PrintStream.println:(Ljava/lang/St ring;)V 49: return </init></init></init></init>
m2
public class DataType { public static void main(String args[]) { DataType dt = new DataType(); dt.m21(); dt.m22(); } public void m21() { Integer a = new Integer(100); Integer b = new Integer(100); System.out.println("m21 result " + (a == b)); } public void m22() { Integer a = new Integer(128); Integer b = new Integer(128); System.out.println("m22 result " + (a == b)); } }
出力された結果は
m21 result false m22 result false
a と b は依然として 2 つのオブジェクトです
javap内容
すごい
m3
public void m21(); Code: 0: new #44; //class java/lang/Integer 3: dup 4: bipush 100 6: invokespecial #46; //Method java/lang/Integer."<init>":(I)V 9: astore_1 10: new #44; //class java/lang/Integer 13: dup 14: bipush 100 16: invokespecial #46; //Method java/lang/Integer."<init>":(I)V 19: astore_2 20: getstatic #53; //Field java/lang/System.out:Ljava/io/PrintStream; 23: new #59; //class java/lang/StringBuilder 26: dup 27: ldc #84; //String m21 result 29: invokespecial #63; //Method java/lang/StringBuilder."<init>":(Ljava/la ng/String;)V 32: aload_1 33: aload_2 34: if_acmpne 41 37: iconst_1 38: goto 42 41: iconst_0 42: invokevirtual #66; //Method java/lang/StringBuilder.append:(Z)Ljava/la ng/StringBuilder; 45: invokevirtual #70; //Method java/lang/StringBuilder.toString:()Ljava/l ang/String; 48: invokevirtual #74; //Method java/io/PrintStream.println:(Ljava/lang/St ring;)V 51: return public void m22(); Code: 0: new #44; //class java/lang/Integer 3: dup 4: sipush 128 7: invokespecial #46; //Method java/lang/Integer."<init>":(I)V 10: astore_1 11: new #44; //class java/lang/Integer 14: dup 15: sipush 128 18: invokespecial #46; //Method java/lang/Integer."<init>":(I)V 21: astore_2 22: getstatic #53; //Field java/lang/System.out:Ljava/io/PrintStream; 25: new #59; //class java/lang/StringBuilder 28: dup 29: ldc #86; //String m22 result 31: invokespecial #63; //Method java/lang/StringBuilder."<init>":(Ljava/la ng/String;)V 34: aload_1 35: aload_2 36: if_acmpne 43 39: iconst_1 40: goto 44 43: iconst_0 44: invokevirtual #66; //Method java/lang/StringBuilder.append:(Z)Ljava/la ng/StringBuilder; 47: invokevirtual #70; //Method java/lang/StringBuilder.toString:()Ljava/l ang/String; 50: invokevirtual #74; //Method java/io/PrintStream.println:(Ljava/lang/St ring;)V 53: return
結果の印刷
public class DataType { public static void main(String args[]) { DataType dt = new DataType(); dt.m31(); dt.m32(); } public void m31() { Integer a = 100; Integer b = 100; System.out.println("m31 result " + (a == b)); } public void m32() { Integer a = 128; Integer b = 128; System.out.println("m32 result " + (a == b)); } }
最初のものが真で、二番目のものが偽なのはなぜですか? javap によって解析されたデータを観察します
javap 解析されたコンテンツ
m31 result true m32 result false
m4
public void m31(); Code: 0: bipush 100 2: invokestatic #49; //Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 5: astore_1 6: bipush 100 8: invokestatic #49; //Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 11: astore_2 12: getstatic #53; //Field java/lang/System.out:Ljava/io/PrintStream; 15: new #59; //class java/lang/StringBuilder 18: dup 19: ldc #88; //String m31 result 21: invokespecial #63; //Method java/lang/StringBuilder."<init>":(Ljava/la ng/String;)V 24: aload_1 25: aload_2 26: if_acmpne 33 29: iconst_1 30: goto 34 33: iconst_0 34: invokevirtual #66; //Method java/lang/StringBuilder.append:(Z)Ljava/la ng/StringBuilder; 37: invokevirtual #70; //Method java/lang/StringBuilder.toString:()Ljava/l ang/String; 40: invokevirtual #74; //Method java/io/PrintStream.println:(Ljava/lang/St ring;)V 43: return public void m32(); Code: 0: sipush 128 3: invokestatic #49; //Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 6: astore_1 7: sipush 128 10: invokestatic #49; //Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 13: astore_2 14: getstatic #53; //Field java/lang/System.out:Ljava/io/PrintStream; 17: new #59; //class java/lang/StringBuilder 20: dup 21: ldc #90; //String m32 result 23: invokespecial #63; //Method java/lang/StringBuilder."<init>":(Ljava/la ng/String;)V 26: aload_1 27: aload_2 28: if_acmpne 35 31: iconst_1 32: goto 36 35: iconst_0 36: invokevirtual #66; //Method java/lang/StringBuilder.append:(Z)Ljava/la ng/StringBuilder; 39: invokevirtual #70; //Method java/lang/StringBuilder.toString:()Ljava/l ang/String; 42: invokevirtual #74; //Method java/io/PrintStream.println:(Ljava/lang/St ring;)V 45: return
結果を印刷する
public class DataType { public static void main(String args[]) { DataType dt = new DataType(); dt.m41(); dt.m42(); } public void m41() { Integer a = Integer.valueOf(100); Integer b = 100; System.out.println("m41 result " + (a == b)); } public void m42() { Integer a = Integer.valueOf(128); Integer b = 128; System.out.println("m42 result " + (a == b)); } }
javap parsed content
m41 result true m42 result false
分析
javap Java コンパイラによって生成されたバイトコードを逆コンパイルして表示できるツールが付属しています (上記のコードは javap -c DataType のみを使用しています)。コードを分析するための優れたツールです。詳しい使用方法については、Google で調べてください。
まず、m4 を見てください。実行結果に「true」が表示されるのはなぜですか? true は、a と b が同じオブジェクトであることを意味します。
しかし、オブジェクト a は Integer.valueOf() を呼び出して生成され、オブジェクト b は自動ボックス化によって生成されるのはなぜでしょうか。バイトコードをもう一度見てみましょう。結局のところ、Java プログラムはバイトコードを実行する仮想マシンに依存して実装されています。
m41 このメソッドは valueOf() を 1 回だけ適用しますが、バイトコード内に 2 回現れます。これは、valueOf() がオートボクシング中にも呼び出されることを示しています。
以下は valueOf() の具体的な実装です
public void m41(); Code: 0: bipush 100 2: invokestatic #49; //Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 5: astore_1 6: bipush 100 8: invokestatic #49; //Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 11: astore_2 12: getstatic #53; //Field java/lang/System.out:Ljava/io/PrintStream; 15: new #59; //class java/lang/StringBuilder 18: dup 19: ldc #92; //String m41 result 21: invokespecial #63; //Method java/lang/StringBuilder."<init>":(Ljava/la ng/String;)V 24: aload_1 25: aload_2 26: if_acmpne 33 29: iconst_1 30: goto 34 33: iconst_0 34: invokevirtual #66; //Method java/lang/StringBuilder.append:(Z)Ljava/la ng/StringBuilder; 37: invokevirtual #70; //Method java/lang/StringBuilder.toString:()Ljava/l ang/String; 40: invokevirtual #74; //Method java/io/PrintStream.println:(Ljava/lang/St ring;)V 43: return public void m42(); Code: 0: sipush 128 3: invokestatic #49; //Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 6: astore_1 7: sipush 128 10: invokestatic #49; //Method java/lang/Integer.valueOf:(I)Ljava/lang/In teger; 13: astore_2 14: getstatic #53; //Field java/lang/System.out:Ljava/io/PrintStream; 17: new #59; //class java/lang/StringBuilder 20: dup 21: ldc #94; //String m42 result 23: invokespecial #63; //Method java/lang/StringBuilder."<init>":(Ljava/la ng/String;)V 26: aload_1 27: aload_2 28: if_acmpne 35 31: iconst_1 32: goto 36 35: iconst_0 36: invokevirtual #66; //Method java/lang/StringBuilder.append:(Z)Ljava/la ng/StringBuilder; 39: invokevirtual #70; //Method java/lang/StringBuilder.toString:()Ljava/l ang/String; 42: invokevirtual #74; //Method java/io/PrintStream.println:(Ljava/lang/St ring;)V 45: return }
[-128, 127] の間の数値、valueOf はキャッシュ内のオブジェクトを返すため、2 つの呼び出しは同じオブジェクトを返します。
読んでいただきありがとうございます、皆さんのお役に立てれば幸いです、このサイトをサポートしていただきありがとうございます!
Java のボックス化とアンボックス化の詳細な説明とサンプル コード関連の記事については、PHP 中国語 Web サイトに注目してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

Video Face Swap
完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











一部のアプリケーションが適切に機能しないようにする会社のセキュリティソフトウェアのトラブルシューティングとソリューション。多くの企業は、内部ネットワークセキュリティを確保するためにセキュリティソフトウェアを展開します。 ...

多くのアプリケーションシナリオでソートを実装するために名前を数値に変換するソリューションでは、ユーザーはグループ、特に1つでソートする必要がある場合があります...

システムドッキングでのフィールドマッピング処理は、システムドッキングを実行する際に難しい問題に遭遇することがよくあります。システムのインターフェイスフィールドを効果的にマッピングする方法A ...

intellijideaultimatiateバージョンを使用してスプリングを開始します...

Javaオブジェクトと配列の変換:リスクの詳細な議論と鋳造タイプ変換の正しい方法多くのJava初心者は、オブジェクトのアレイへの変換に遭遇します...

データベース操作にMyBatis-Plusまたはその他のORMフレームワークを使用する場合、エンティティクラスの属性名に基づいてクエリ条件を構築する必要があることがよくあります。あなたが毎回手動で...

eコマースプラットフォーム上のSKUおよびSPUテーブルの設計の詳細な説明この記事では、eコマースプラットフォームでのSKUとSPUのデータベース設計の問題、特にユーザー定義の販売を扱う方法について説明します。

Redisキャッシュソリューションは、製品ランキングリストの要件をどのように実現しますか?開発プロセス中に、多くの場合、ランキングの要件に対処する必要があります。
