java有装箱和拆箱吗_Java中装箱和拆箱,你真的都懂么?
在給部門做分享的時候,一位同學(xué)提問說一直沒搞明白Java的裝箱和拆箱,讓我給講解下,所以才有了下面這篇文章:
本次文章根據(jù)PPT分享整理而成,會有5點:
1、什么是裝箱和拆箱?
2、基本數(shù)據(jù)類型和包裝類型區(qū)別
3、示例演示
4、示例代碼分析
5、總結(jié)
1、什么是裝箱和拆箱?
概念:
裝箱是將基本類型轉(zhuǎn)換為包裝類型
拆箱是想包裝類型轉(zhuǎn)換為基本類型
示例:
Integer a = new Integer(1); //裝箱
int b = a.intVal(); //拆箱
//JDK1.5開始自動裝箱和拆箱
Integer a = 1; //自動裝箱
int b = a;//自動拆箱
2、基本數(shù)據(jù)類型和包裝類型區(qū)別
概念:
基本數(shù)據(jù)類型:不需要在堆中分配內(nèi)存,直接將變量的值存儲在堆棧上
包裝類型:基本數(shù)據(jù)類型不具有對象的性質(zhì),為了讓其具有對象性質(zhì),故出現(xiàn)包裝類型,將基本類型包裝,使其具有對象性質(zhì)
相互轉(zhuǎn)換:
基本數(shù)據(jù)類型轉(zhuǎn)換為包裝類型
Integer.valueOf(int);
...
包裝類型轉(zhuǎn)換為基本數(shù)據(jù)類型
intValue();
longValue();
...
基本類型和包裝類型對應(yīng)關(guān)系
基本數(shù)據(jù)類型
包裝類型
byte
Byte
char
Character
short
Short
int
Integer
long
Long
float
Float
double
Double
boolean
Boolean
3、示例演示
// 如果您能全部回答正確,您可以跳過后面章節(jié):
public static void main(String[] args) {
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 129;
Integer f = 129;
Long g = 3L;
System.out.println(c == d);
System.out.println(e == f);
System.out.println(c == (a+b));
System.out.println(c.equals(a+b));
System.out.println(e.equals(f));
System.out.println(g == (a+b));
System.out.println(g.equals(a+b));
}
4、示例代碼分析
// 反編譯代碼,注意:其中中文注釋是我加的,便于大家查看
public static void main(java.lang.String[]);
Code:
0: iconst_1
1: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
4: astore_1
5: iconst_2
6: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
9: astore_2
10: iconst_3
11: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
14: astore_3
15: iconst_3
16: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
19: astore 4
21: sipush 129
24: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
27: astore 5
29: sipush 129
32: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
35: astore 6
37: ldc2_w #3 // long 3l
40: invokestatic #5 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
43: astore 7
45: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
48: aload_3
49: aload 4
51: if_acmpne 58 //c==d,注意這里執(zhí)行進行了引用比較
54: iconst_1
55: goto 59
58: iconst_0
59: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V
62: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
65: aload 5
67: aload 6
69: if_acmpne 76 //e==f,注意這里執(zhí)行進行了引用比較
72: iconst_1
73: goto 77
76: iconst_0
77: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V
80: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
83: aload_3
84: invokevirtual #8 // Method java/lang/Integer.intValue:()I
87: aload_1
88: invokevirtual #8 // Method java/lang/Integer.intValue:()I
91: aload_2
92: invokevirtual #8 // Method java/lang/Integer.intValue:()I
95: iadd // 這里執(zhí)行了(a+b)
96: if_icmpne 103 // 這里執(zhí)行c==(a+b),數(shù)值比較
99: iconst_1
100: goto 104
103: iconst_0
104: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V
107: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
110: aload_3
111: aload_1
112: invokevirtual #8 // Method java/lang/Integer.intValue:()I //拆箱
115: aload_2
116: invokevirtual #8 // Method java/lang/Integer.intValue:()I //拆箱
119: iadd
120: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; //裝箱
123: invokevirtual #9 // Method java/lang/Integer.equals:(Ljava/lang/Object;)Z //c.equals(a+b)
126: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V
129: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
132: aload 5
134: aload 6
136: invokevirtual #9 // Method java/lang/Integer.equals:(Ljava/lang/Object;)Z //e.equals(f)
139: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V
142: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
145: aload 7
147: invokevirtual #10 // Method java/lang/Long.longValue:()J //Long 拆箱
150: aload_1
151: invokevirtual #8 // Method java/lang/Integer.intValue:()I //Integer 拆箱
154: aload_2
155: invokevirtual #8 // Method java/lang/Integer.intValue:()I //Integer 拆箱
158: iadd // (a+b)
159: i2l // (a+b)結(jié)果轉(zhuǎn)換為long類型
160: lcmp // 執(zhí)行 g == (a+b) 數(shù)值比較
161: ifne 168
164: iconst_1
165: goto 169
168: iconst_0
169: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V
172: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
175: aload 7
177: aload_1
178: invokevirtual #8 // Method java/lang/Integer.intValue:()I //Integer 拆箱
181: aload_2
182: invokevirtual #8 // Method java/lang/Integer.intValue:()I //Integer 拆箱
185: iadd // (a+b)數(shù)值相加
186: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; // Integer裝箱
189: invokevirtual #11 // Method java/lang/Long.equals:(Ljava/lang/Object;)Z //執(zhí)行g(shù).equals(a+b)
192: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V
195: return
}
結(jié)合反編譯代碼,給出的分析:
當(dāng)我們定義Integer a = 1;時實際執(zhí)行Integer.valueOf(1),返回Integer對象
// 默認IntegerCache.low = -128, IntegerCache.high = 127
// 但是可以指定"java.lang.Integer.IntegerCache.high"
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
當(dāng)我們給a、b、c和d賦值時,是在-128-127范圍內(nèi),直接從緩存中取值,而執(zhí)行e和f賦值時,會執(zhí)行new Integer(int),所以他們是不同的Integer對象;
"=="符只有遇到運算符才會執(zhí)行“自動拆箱”
當(dāng)執(zhí)行equals比較,會執(zhí)行類型判斷和數(shù)值比較
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
運行結(jié)果
c == d:true //沒有自動拆箱,直接比較引用
e == f:false //沒有自動拆箱,直接比較引用
c == (a+b):true //執(zhí)行“自動拆箱”,進行數(shù)值比較
c.equals(a+b):true //a+b拆箱相加,然后自動裝箱,再執(zhí)行equals
e.equals(f):true //沒有執(zhí)行裝箱和拆箱
g == (a+b):true //自動拆箱,執(zhí)行idd,進行數(shù)值比較
g.equals(a+b):false //a+b拆箱相加,然后自動裝箱,再執(zhí)行equals
5、總結(jié)
包裝類型的數(shù)值比較,要注意"=="符號的使用,最好使用equals進行數(shù)值比較,因為equals會自動執(zhí)行拆箱,進行數(shù)值比較
總結(jié)
以上是生活随笔為你收集整理的java有装箱和拆箱吗_Java中装箱和拆箱,你真的都懂么?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CenterPoint的环境配置erro
- 下一篇: java base64解码出错_Java