java的自动装箱_java自动装箱的陷阱

自动装箱和拆箱是java的一颗语法糖,在给我们带来使用便利的同时也带来一些疑惑,请看下面的代码:

1 public classTestClass {2 public static voidmain(String args[]) {3 Integer a = 1;4 Integer b = 2;5 Integer c = 3;6 Integer d = 3;7 Integer e = 321;8 Integer f = 321;9 Long g = 3L;10

11 System.out.println(c ==d);12 System.out.println(e ==f);13 System.out.println(c == (a+b));14 System.out.println(c.equals(a+b));15 System.out.println(g == (a+b));16 System.out.println(g.equals(a+b));17 }18 }

大家看一下上面这段代码的输出结果应该是什么?

答案是:

T

F

T

T

T

F

这样的答案是不是出乎很多人的意料呢?我们一一来分析。

1. 首先我们明确一下"=="和equals方法的作用。

"==":如果是基本数据类型,则直接对值进行比较,如果是引用数据类型,则是对他们的地址进行比较

equals方法继承自Object类,在具体实现时可以覆盖父类中的实现。看一下Object中qeuals的源码发现,它的实现也是对对象的地址进行比较,此时它和"=="的作用相同。而JDK类中有一些类覆盖了oject类的equals()方法,比较规则为:如果两个对象的类型一致,并且内容一致,则返回true,这些类有:

java.io.file,java.util.Date,java.lang.string,包装类(Integer,Double等)。

2. java的常量池技术。java中的基本类型的包装类、其中Byte、Boolean、Short、Character、Integer、Long实现了常量池技术,(除了Boolean,都只对小于128的值才支持)。什么意思呢?对于范围在-128到127大小的数据,java会在常量池中提前生成这个范围的数据,只要是指向这些数据的包装类,都有相同的地址。而不在这个范围内的数据会到堆上new一个出来。

3. "=="在遇到算术运算符的情况下不会自动拆箱,以及他们的equals方法不处理数据类型转换的关系。

因此,对于 System.out.println(c == d); 他们指向常量池中同一个地址,返回True。

对于 System.out.println(e == f); 他们的值大于127,即使值相同,但是对应不同的内存地址,返回false。

对于 System.out.println(c == (a+b)); 他们指向常量池中同一个地址,返回True。

对于 System.out.println(c.equals(a+b)); 他们的值相同,而且类型相同,返回true。

对于 System.out.println(g == (a+b)); 他们指向常量池中同一个地址,返回True。

对于 System.out.println(g.equals(a+b)); 他们的值相同但是类型不同,返回false。

这下明白了吧?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值