Javaパッキングとボクシングの詳細な説明
序文:
パッキングとボクシングの概念を理解するには、Javaデータ型を理解する必要があります
ボックス:対応する参照タイプを備えた基本タイプをパッケージして、オブジェクトのプロパティを持たせるようにします。 integerにパッケージ化され、フロートがフロートにパッケージ化されています
ボクシングの解除:ボクシングとは対照的に、参照タイプのオブジェクトを価値タイプのデータに簡素化します
整数a = 100;これは自動ボクシングです
次のコードを参照してください
M1
Public Class void args []){dt.m11() {integer a = new Integer(128); System.out.println( "m12 result" +(a == b));印刷の結果は何ですか?
M11結果false M12結果false
「==」はアドレスを比較しますが、オブジェクトAとBのアドレスは異なります。つまり、それらは2つのオブジェクトであるため、両方とも偽です
Javapを介してBytecodeを解析すると、コンテンツは次のとおりです
Public void M11:0:new#44; /lang/integer; Java/Lang/System:Ljava/PrintStream:New#59; OAD_2 30:IF_ACMPNE 37 33:ICONST_1 34:GOTO 38 37:ICONST_0 38:InvokeVirtual#66; Java/StringBuilder.(Z)Ljava/StringBuilder:InvokeVirtual#70; v 47:public void m12(); // Java/Lang/Integer "<(i)v 10:store_1:invokestatic#49;新しい#59; Invokespecial#63;メソッドJava/StringBuilder.(Z)Ljava/StringBuilder:InvokeVirtual#70; InvokeVirtual#74; //メソッドJava/io/printStream.println:(ljava/lang/string;)v 49:return </init> </init> </init> </init>
M2
パブリックデータ型{String args []){dt.m21(); } public void m22(){integer a = new Integer(128); integer(128);印刷の結果はです
M21結果falsem22結果false
AとBはまだ2つのオブジェクトです
Javapの解析コンテンツ
Public void M21():0:new#44; ; //メソッドJava/Lang/Integer。 "<int>" :( i)v 19:store_2 20: Java/Lang/System:Ljava/PrintStream:New#59; 3:ALOAD_2 34:IF_ACMPNE 41 37:ICONST_1 38:GOTO 42 41:ICONST_0 42:InvokeVirtual#66; Java/StringBuilder:(Z)Ljava/StringBuilder:InvokeVirtual#70; v 51:returnpublic void m22(); // Java/Lang/Integer。 "<init>" :( i)v 10:store_1 11:new#44; :ljava/io/printStream:new#59; #86; Invokespecial#63; /メソッドJava/StringBuilder; InvokeVirtual#70; Java/Lang/StringBuilder.ToString :()ljava/lang/string:invokeVirtual#74;
M3
Public Class void args []){dt.m31(); eger a = 128; }}結果を印刷します
M31結果truem32結果false
なぜ最初のものと2番目のものが偽りがあるのですか? Javapによって解析されたデータを観察します
Javapの解析コンテンツ
パブリックM31:0:Invokestatic#49; :GetStatic#53; Java/Lang/StringBuilder 18:DUP 19:LDC#88; Invokespecial#63; #70; /lang/integer.valueof :(i)Ljava/lang/integer; Java/integer.value:(i)Ljava/Integer; 63; //メソッドJava/Lang/StringBuilder。 "<init>" :( ljava/lang/string;)v 26:aload_1:aload_2 28: IF_ACMPNE 31:ICONST_1 35:ICONST_0 36:InvokeVirtual#66; 42:InvokeVirtual#74; //メソッドJava/io/printstring.println:(ljava/lang/string;)v 45:return
M4
Public Class void main(] {dt.m41(); ID M42(){integer a = integer.valueof(128); system.out.println( "m42 result" +(a == b));結果を印刷します
M41結果truem42結果false
Javapの解析コンテンツ
パブリックM41:0:Invokestatic#49; :GetStatic#53; Java/Lang/StringBuilder 18:LDC#92; // Invokespecial#63; #70; /lang/integer.valueof :(i)Ljava/lang/integer; Java/integer.value:(i)Ljava/integer; 63; //メソッドJava/Lang/StringBuilder。 "<init>" :( ljava/lang/string;)v 26:aload_1:aload_2 28: IF_ACMPNE 31:ICONST_1 35:ICONST_0 36:InvokeVirtual#66; 42:InvokeVirtual#74;メソッドJava/io/printstream.println:(ljava/lang/string;)v 45:return}
分析します
Javapは、Javaコンパイラによって生成されたBytecodeを削除または表示することができます。
最初にM4を見てみましょう。
しかし、オブジェクトAはinteger.valueof()を呼び出し、bはオブジェクトで生成されます。結局のところ、Javaプログラムは再びBytecodeに依存しています。
M41メソッドはvalueof()を1回しか適用しませんが、バイトコードで2回表示されます。つまり、valueof()は自動ボクシング中にも呼ばれます。
以下は、valueof()の具体的な実装です
/** *指定された * <tt> int </tt>を表す<tt> integer </tt>インスタンスを返します</tt>インスタンスが必要ない場合、この方法は一般に、@link #integer( an <code> int </code> @return <tt> </tt>インスタンス<tt> i </tt>/public static integer valueof(int i){int i) }[-128、127]の間の数字では、ValueOFはキャッシュ内のオブジェクトを返します。そのため、2つの呼び出しは同じオブジェクトを返します。
読んでくれてありがとう、私はそれがあなたを助けてくれることを願っています。