前言:
装箱:把基本类型用它们相应的引用类型包装起来,使其具有对象的性质。int包装成Integer、float包装成Float
?
|
1
2
|
Integer a = 100; 这是自动装箱 (编译器调用的是static Integer valueOf(int i))
int b = new Integer(100); 这是自动拆箱
|
看下面一段代码
m1
?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
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));
}
}
|
打印结果是什么?
?
|
1
2
|
m11 result false
m12 result false
|
“==”比较的是地址,而a和b两个对象的地址不同,即是两个对象,所以都是false
通过javap解析字节码,内容如下
?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
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
?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
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));
}
}
|
打印结果是
?
|
1
2
|
m21 result false
m22 result false
|
a和b仍是两个对象
javap解析内容
?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
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
|
m3
?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
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));
}
}
|
打印结果
?
|
1
2
|
m31 result true
m32 result false
|
为什么有第一个是true,第二个是false呢?观察javap解析的数据
javap解析内容
?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
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
|
m4
?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
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));
}
}
|
打印结果
?
|
1
2
|
m41 result true
m42 result false
|
javap解析内容
?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
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
}
|
分析
javap是Java自带的一个工具,可以反编译,也可以查看Java编译器生成的字节码(上面代码只使用了javap -c DataType),是分析代码的一个好工具,具体怎么使用请Google一下
先看一下m4,为什么运行结果中出现了“true”呢,true说明a、b是同一个对象。
但a对象是调用Integer.valueOf()生成的,b是通过自动装箱生成的对象,为什么会是同一个对象呢?再看一下字节码吧,毕竟Java程序是依靠虚拟机运行字节码实现的。
m41这个方法只适用了一次valueOf(),但字节码中出现了两次,说明自动装箱时也调用了valueOf()。
下面是valueOf()具体实现
?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
/**
* Returns a <tt>Integer</tt> instance representing the specified
* <tt>int</tt> value.
* If a new <tt>Integer</tt> instance is not required, this method
* should generally be used in preference to the constructor
* {@link #Integer(int)}, as this method is likely to yield
* significantly better space and time performance by caching
* frequently requested values.
*
* @param i an <code>int</code> value.
* @return a <tt>Integer</tt> instance representing <tt>i</tt>.
* @since 1.5
*/
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}
|
在【-128,127】之间的数字,valueOf返回的是缓存中的对象,所以两次调用返回的是同一个对象。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
原文链接:http://blog.csdn.net/qq_35101189/article/details/54318594
相关文章
猜你喜欢
- 64M VPS建站:如何选择最适合的网站建设平台? 2025-06-10
- ASP.NET本地开发时常见的配置错误及解决方法? 2025-06-10
- ASP.NET自助建站系统的数据库备份与恢复操作指南 2025-06-10
- 个人网站服务器域名解析设置指南:从购买到绑定全流程 2025-06-10
- 个人网站搭建:如何挑选具有弹性扩展能力的服务器? 2025-06-10
TA的动态
- 2025-07-10 怎样使用阿里云的安全工具进行服务器漏洞扫描和修复?
- 2025-07-10 怎样使用命令行工具优化Linux云服务器的Ping性能?
- 2025-07-10 怎样使用Xshell连接华为云服务器,实现高效远程管理?
- 2025-07-10 怎样利用云服务器D盘搭建稳定、高效的网站托管环境?
- 2025-07-10 怎样使用阿里云的安全组功能来增强服务器防火墙的安全性?
快网idc优惠网
QQ交流群
您的支持,是我们最大的动力!
热门文章
-
2025-05-29 35
-
2025-05-25 77
-
2025-06-04 90
-
2025-05-27 78
-
2025-05-25 40
热门评论

