Java 포장 및 Unboxing에 대한 자세한 설명
머리말:
포장 및 Unboxing의 개념을 이해하려면 Java 데이터 유형을 이해해야합니다.
상자 : 해당 참조 유형의 기본 유형을 패키지로하여 객체의 속성을 갖도록합니다. int int integer로 패키지, 플로트로 플로트로 플로트
Unboxing : 권투와 달리 값 유형의 데이터에 대한 참조 유형의 객체를 단순화합니다.
정수 a = 100; 이것은 자동 권투입니다 (컴파일러는 정적 정수 값을 호출합니다 (int i)) int b = new Integer (100); 이것은 자동 권투입니다
다음 코드를 참조하십시오
M1
공개 클래스 데이터 유형 {public static void main (String args []) {dataType dt = new DataType (); dt.m11 (); dt.m12 (); } public void m11 () {Integer a = new Integer (100); 정수 b = 100; System.out.println ( "M11 result" + (a == b)); } public void m12 () {Integer a = new Integer (128); 정수 B = 128; System.out.println ( "M12 result" + (a == b)); }}인쇄 결과는 무엇입니까?
M11 결과 false m12 결과 false
"=="는 주소를 비교하고, 두 객체 A와 B의 주소는 다르지만, 즉 두 객체이므로 둘 다 False입니다.
Javap을 통해 바이트 코드를 구문 분석하면 컨텐츠는 다음과 같습니다
공개 void M11 (); 코드 : 0 : 새로운 #44; // 클래스 Java/Lang/Integer 3 : Dup 4 : Bipush 100 6 : Invokescial #46; // 메소드 java/lang/integer. "<init>":( i) v 9 : Store_1 10 : Bipush 100 12 : Invokestatic #49; // 메소드 java/lang/integer.valueof : (i) ljava/lang/integer; 15 : Stor_2 16 : Getstatic #53; // 필드 java/lang/system.out : ljava/io/printstream; 19 : 새로운 #59; // 클래스 Java/Lang/StringBuilder 22 : DUP 23 : LDC #61; // 문자열 M11 결과 25 : invokescial #63; // 메소드 java/lang/stringbuilder. "<init>":( ljava/lang/string;) v 28 : aload_1 29 : aload_2 30 : if_acmpne 37 33 : iconst_1 34 : goto 37 : iconst_0 38 : invokevirtual #66; // 메소드 java/lang/stringbuilder.append : (z) ljava/lang/stringbuilder; 41 : InvokeVirtual #70; // 메소드 java/lang/stringbuilder.tostring :() ljava/lang/string; 44 : InvokeVirtual #74; // 메소드 java/io/printstream.println : (ljava/lang/string;) v 47 : return public void m12 (); 코드 : 0 : 새로운 #74; // 클래스 Java/Lang/Integer 3 : Dup 4 : Sipush 128 7 : Invokescial #46; // 메소드 Java/Lang/Integer. "<init>":( i) v 10 : store_1 11 : Sipush 128 14 : Invokestatic #49; // 메소드 java/lang/integer.valueof : (i) ljava/lang/integer; 17 : Store_2 18 : Getstatic #53; // 필드 java/lang/system.out : ljava/io/printstream; 21 : 새로운 #59; // 클래스 Java/Lang/StringBuilder 24 : DUP 25 : LDC #82; // 문자열 m12 결과 27 : invokescial #63; // 메소드 java/lang/stringbuilder.append : (z) ljava/lang/stringbuilder; 43 : InvokeVirtual #70; // 메소드 java/lang/stringbuilder.tostring :() ljava/lang/stringbuilder; 46 : InvokeVirtual #74; // 메소드 java/io/printstream.println : (ljava/lang/string;) v 49 : return </init> </init> </init> </init>
M2
공개 클래스 데이터 유형 {public static void main (String args []) {dataType dt = new DataType (); dt.m21 (); dt.m22 (); } public void m21 () {Integer a = new Integer (100); 정수 B = 새로운 정수 (100); System.out.println ( "m21 result" + (a == b)); } public void m22 () {Integer a = new Integer (128); 정수 B = 새로운 정수 (128); System.out.println ( "M22 result" + (a == b)); }}인쇄 결과가 있습니다
m21 결과 falsem22 결과 false
A와 B는 여전히 두 개의 객체입니다
Javap 구문 분석 콘텐츠
공공 void m21 (); 코드 : 0 : 새로운 #44; // 클래스 Java/Lang/Integer 3 : Dup 4 : Bipush 100 6 : Invokescial #46; // 메소드 java/lang/integer. "<init>":( i) v 9 : Store_1 10 : 새로운 #44; // 클래스 Java/Lang/Integer 13 : DUP 14 : Bipush 100 16 : Invokescial #46; // 메소드 java/lang/integer. "<init>":( i) v 19 : Store_2 20 : getstatic #53; // 필드 java/lang/system.out : ljava/io/printstream; 23 : 새로운 #59; // 클래스 Java/Lang/StringBuilder 26 : DUP 27 : LDC #84; // 문자열 m21 결과 29 : invokescial #63; // 메소드 java/lang/stringbuilder. "<init>":( ljava/lang/string;) v 32 : aload_1 33 : aload_2 34 : if_acmpne 41 37 : iconst_1 38 : goto 42 41 : iconst_0 42 : invorkokevirtual #66; // 메소드 java/lang/stringbuilder.append : (z) ljava/lang/stringbuilder; 45 : InvokeVirtual #70; // 메소드 java/lang/stringbuilder.tostring :() ljava/lang/string; 48 : InvokeVirtual #74; // 메소드 java/io/printstream.println : (ljava/lang/string;) v 51 : returnpublic void m22 (); 코드 : 0 : 새로운 #74; // 클래스 Java/Lang/Integer 3 : Dup 4 : Sipush 128 7 : Invokescial #46; // 메소드 java/lang/integer. "<init>":( i) v 10 : Store_1 11 : 새로운 #44; // 클래스 Java/Lang/Integer 14 : Dup 15 : Sipush 128 18 : Invokescial #46; // 메소드 java/lang/integer. "<init>":( i) v 21 : Store_2 22 : getstatic #53; // 필드 java/lang/system.out : ljava/io/printstream; 25 : 새로운 #59; // 클래스 Java/Lang/StringBuilder 28 : DUP 29 : LDC 47 : InvokeVirtual #70; // 메소드 java/lang/stringbuilder.append : (z) ljava/lang/stringbuilder; 47 : InvokeVirtual #70; // 메소드 Java/Lang/StringBuilder; 40 : InvokeVirtual #70; // 메소드 java/lang/stringbuilder.append : (z) ljava/lang/stringbuilder; 47 : InvokeVirtual #70; // 메소드 Java/Lang/StringBuilder; java/lang/stringbuilder.tostring :() ljava/lang/string; 50 : InvokeVirtual #74; // 메소드 java/io/printstream.println : (ljava/lang/string;) v 53 : return
M3
공개 클래스 데이터 유형 {public static void main (String args []) {dataType dt = new DataType (); dt.m31 (); dt.m32 (); } public void m31 () {정수 a = 100; 정수 b = 100; System.out.println ( "m31 result" + (a == b)); } public void m32 () {정수 a = 128; 정수 B = 128; System.out.println ( "M32 result" + (a == b)); }}인쇄 결과
m31 결과 truem32 결과 false
왜 첫 번째 진실이 있고 두 번째가 거짓이 있습니까? Javap이 구문 분석 한 데이터를 관찰하십시오
Javap 구문 분석 콘텐츠
공공 void m31 (); 코드 : 0 : Bipush 100 2 : Invokestatic #49; // 메소드 java/lang/integer.valueof : (i) ljava/lang/integer; 5 : Store_1 6 : Bipush 100 8 : Invokestatic #49; // 메소드 java/lang/integer.valueof : (i) ljava/lang/integer; 11 : Store_2 12 : Getstatic #53; // 필드 java/lang/system.out : ljava/io/printstream; 15 : 새로운 #59; // 클래스 Java/Lang/StringBuilder 18 : DUP 19 : LDC #88; // 문자열 m31 결과 21 : invokescial #63; // 메소드 java/lang/stringbuilder.append : (z) ljava/lang/stringbuilder; 37 : InvokeVirtual #70; // 메소드 java/lang/stringbuilder.tostring :() ljava/lang/string; 40 : InvokeVirtual #74; // 메소드 java/io/printstream.println : (ljava/lang/string;) v 43 : returnpublic void m32 (); 코드 : 0 : Sipush 128 3 : Invokestatic #49; // 메소드 java/lang/integer.valueof : (i) ljava/lang/integer; 6 : astore_1 7 : Sipush 128 10 : Invokestatic #49; // 메소드 java/lang/integer.valueof : (i) ljava/lang/integer; 13 : Store_2 14 : Getstatic #53; // 필드 java/lang/system.out : ljava/io/printstream; 17 : 새로운 #59; // 클래스 Java/Lang/StringBuilder 20 : DUP 21 : LDC #90; // 문자열 m32 결과 23 : invokescial #63; // 메소드 java/lang/stringbuilder. "<init>":( ljava/lang/string;) v 26 : aload_1 27 : aload_2 28 : if_acmpne 35 31 : iconst_1 32 : goto 36 35 : iconst_0 36 : invokevirtual #66; // 메소드 java/lang/stringbuilder.append : (z) ljava/lang/stringbuilder; 39 : InvokeVirtual #70; // 메소드 java/lang/stringbuilder.tostring :() ljava/lang/string; 42 : InvokeVirtual #74; // 메소드 java/io/printstring.println : (ljava/lang/string;) v 45 : return
M4
공개 클래스 데이터 유형 {public static void main (String args []) {dataType dt = new DataType (); dt.m41 (); dt.m42 (); } public void m41 () {Integer a = integer.valueof (100); 정수 b = 100; System.out.println ( "m41 result" + (a == b)); } public void m42 () {Integer a = integer.valueof (128); 정수 B = 128; System.out.println ( "M42 result" + (a == b)); }}인쇄 결과
m41 결과 truem42 결과 false
Javap 구문 분석 콘텐츠
공공 void m41 (); 코드 : 0 : Bipush 100 2 : Invokestatic #49; // 메소드 java/lang/integer.valueof : (i) ljava/lang/integer; 5 : Store_1 6 : Bipush 100 8 : Invokestatic #49; // 메소드 java/lang/integer.valueof : (i) ljava/lang/integer; 11 : Store_2 12 : Getstatic #53; // 필드 java/lang/system.out : ljava/io/printstream; 15 : 새로운 #59; // 클래스 Java/Lang/StringBuilder 18 : DUP 19 : LDC #92; // 문자열 m41 결과 21 : invokescial #63; // 메소드 java/lang/stringbuilder.append : (z) ljava/lang/stringbuilder; 37 : InvokeVirtual #70; // 메소드 java/lang/stringbuilder.tostring :() ljava/lang/string; 40 : InvokeVirtual #74; // 메소드 java/io/printstream.println : (ljava/lang/string;) v 43 : returnpublic void m42 (); 코드 : 0 : Sipush 128 3 : Invokestatic #49; // 메소드 java/lang/integer.valueof : (i) ljava/lang/integer; 6 : astore_1 7 : Sipush 128 10 : Invokestatic #49; // 메소드 java/lang/integer.valueof : (i) ljava/lang/integer; 13 : Store_2 14 : Getstatic #53; // 필드 java/lang/system.out : ljava/io/printstream; 17 : 새로운 #59; // 클래스 Java/Lang/StringBuilder 20 : DUP 21 : LDC #94; // 문자열 m42 결과 23 : invokescial #63; // 메소드 java/lang/stringbuilder. "<init>":( ljava/lang/string;) v 26 : aload_1 27 : aload_2 28 : if_acmpne 35 31 : iconst_1 32 : goto 36 35 : iconst_0 36 : invokevirtual #66; // 메소드 java/lang/stringbuilder.append : (z) ljava/lang/stringbuilder; 39 : InvokeVirtual #70; // 메소드 java/lang/stringbuilder.tostring :() ljava/lang/string; 42 : InvokeVirtual #74; // 메소드 java/io/printstream.println : (ljava/lang/string;) v 45 : return}
분석
Javap은 Java와 함께 제공되는 도구입니다. Java 컴파일러에 의해 생성 된 Bytecode를 분리하거나 볼 수 있습니다 (위의 코드는 Javap -C DataType 만 사용). 코드를 분석하기에 좋은 도구입니다. 자세한 내용은 Google을 입력하십시오.
먼저 M4를 살펴 보겠습니다. 실행중인 결과에 "true"가 나타나는 이유는 무엇입니까? True는 A와 B가 동일한 객체임을 의미합니다.
그러나 객체 A는 integer.valueof ()를 호출하여 생성되고 B는 자동 권투에서 생성 된 객체입니다. 왜 같은 대상입니까? 바이트 코드를 다시 살펴 보겠습니다. 결국 Java 프로그램은 가상 머신에 의존하여 바이트 코드를 실행합니다.
M41 메소드는 valuef () 만 한 번만 적용되지만 바이트 코드에서 두 번 표시되므로 valueof ()도 자동 권투 중에 호출됩니다.
다음은 ()의 특정 구현입니다.
/** * 지정된 * <tt> int </tt> 값을 나타내는 <tt> integer </tt> 인스턴스를 반환합니다. * 새로운 <tt> 정수 </tt> 인스턴스가 필요하지 않은 경우,이 방법 *은 일반적으로 생성자 * {@link #integer (int)}보다 선호하는 경우에 사용되어야합니다. * * @param i an <code> int </code> 값. * @return a <tt> integer </tt> 인스턴스 <tt> i </tt>. * @Since 1.5 */public static integer valueof (int i) {최종 int 오프셋 = 128; if (i> = -128 && i <= 127) {// return integercache.cache [i + 오프셋];} 새 정수 (i);}를 반환해야합니다.[-128, 127] 사이의 숫자에서 값은 캐시의 객체를 반환하므로 두 호출은 동일한 객체를 반환합니다.
읽어 주셔서 감사합니다. 도움이되기를 바랍니다. 이 사이트를 지원 해주셔서 감사합니다!