java有装箱和拆箱吗_Java中装箱和拆箱,你真的都懂么?

在给部门做分享的时候,一位同学提问说一直没搞明白Java的装箱和拆箱,让我给讲解下,所以才有了下面这篇文章:

本次文章根据PPT分享整理而成,会有5点:

1、什么是装箱和拆箱?

2、基本数据类型和包装类型区别

3、示例演示

4、示例代码分析

5、总结

1、什么是装箱和拆箱?

概念:

装箱是将基本类型转换为包装类型

拆箱是想包装类型转换为基本类型

示例:

Integer a = new Integer(1); //装箱

int b = a.intVal(); //拆箱

//JDK1.5开始自动装箱和拆箱

Integer a = 1; //自动装箱

int b = a;//自动拆箱

2、基本数据类型和包装类型区别

概念:

基本数据类型:不需要在堆中分配内存,直接将变量的值存储在堆栈上

包装类型:基本数据类型不具有对象的性质,为了让其具有对象性质,故出现包装类型,将基本类型包装,使其具有对象性质

相互转换:

基本数据类型转换为包装类型

Integer.valueOf(int);

...

包装类型转换为基本数据类型

intValue();

longValue();

...

基本类型和包装类型对应关系

基本数据类型

包装类型

byte

Byte

char

Character

short

Short

int

Integer

long

Long

float

Float

double

Double

boolean

Boolean

3、示例演示

// 如果您能全部回答正确,您可以跳过后面章节:

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,注意这里执行进行了引用比较

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,注意这里执行进行了引用比较

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 // 这里执行了(a+b)

96: if_icmpne 103 // 这里执行c==(a+b),数值比较

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)结果转换为long类型

160: lcmp // 执行 g == (a+b) 数值比较

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)数值相加

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 //执行g.equals(a+b)

192: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V

195: return

}

结合反编译代码,给出的分析:

当我们定义Integer a = 1;时实际执行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);

}

当我们给a、b、c和d赋值时,是在-128-127范围内,直接从缓存中取值,而执行e和f赋值时,会执行new Integer(int),所以他们是不同的Integer对象;

"=="符只有遇到运算符才会执行“自动拆箱”

当执行equals比较,会执行类型判断和数值比较

public boolean equals(Object obj) {

if (obj instanceof Integer) {

return value == ((Integer)obj).intValue();

}

return false;

}

运行结果

c == d:true //没有自动拆箱,直接比较引用

e == f:false //没有自动拆箱,直接比较引用

c == (a+b):true //执行“自动拆箱”,进行数值比较

c.equals(a+b):true //a+b拆箱相加,然后自动装箱,再执行equals

e.equals(f):true //没有执行装箱和拆箱

g == (a+b):true //自动拆箱,执行idd,进行数值比较

g.equals(a+b):false //a+b拆箱相加,然后自动装箱,再执行equals

5、总结

包装类型的数值比较,要注意"=="符号的使用,最好使用equals进行数值比较,因为equals会自动执行拆箱,进行数值比较

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值