软件构造|autoboxing and equality

autoboxing and unboxing

java自动装箱与拆箱(auto boxing and unboxing)是指java编译器能够在原始类型(primitive type)以及它们的包装类之间进行自动转换。

autoboxing

自动装箱(autoboxing)发生于:

  1. 原始类型作为参数传入一个需要相关包装类做参数的函数。

Passed as a parameter to a method that expects an object of the corresponding wrapper class.

  1. 原始类型赋值给对应的包装类时

对于1情况,例子:

List<Integer> list = new ArrayList<Integer>();
list.add(1);

这是我们平常经常用到的语句,向一个List容器中添加数。其中,查看文档可以发现:

boolean add(E e)
Appends the specified element to the end of this list (optional operation).

add函数的参数是泛型E,这里我们声明的list使用了Integer。所以调用list.add(1)时,1作为参数,被自动装箱,成为了Integer

对于2情况,例子:

Integer i = 1;

这也是我们平常常用的java语句,这里1作为primitive type被赋值给Integer,在此过程中,自动装箱为Integer。

unboxing

反过来,从包装类到原始类型就是自动拆箱(unboxing)。
与boxing相似,unboxing 发生于:

  1. 包装类作为参数传入一个需要相关原始类型做参数的函数。

Passed as a parameter to a method that expects a value of the corresponding primitive type.

  1. 原始类型赋值给对应的包装类时

Assigned to a variable of the corresponding primitive type

对于情况1,例子:

Integer a1 = 1;
Integer a2 = 2;
int sum = a1 + a2;

这里Intege类并没有定义+的操作,所以a1 + a2会拆箱成int进行相加。

对于情况2,例子:

Integer i1 = 1;
int i2 = i1;

i1在赋值给i2时,自动拆箱成为int

autoboxing and equality

经验中,我们知道

int x = 1;
int y = 1;

x==y结果为true

Integer x = 1;
Integer y = 1;

x.equals(y)结果为true。但是x==y结果为false
这是因为integer类型重写了equals方法。

Compares this object to the specified object. The result is true if and only if the argument is not null and is an Integer object that contains the same int value as this object.

比较两个Integer实例的实际int值。而==会基于引用进行判断(referential equality),由于x, y 不是指向同一个Integer对象,所以二者==便会返回false

由于java的自动装箱、拆箱机制,程序在相等性判断上,可能会有令人意想不到的结果。

我们观察几个例子。

https://learning.edx.org/course/course-v1:MITx+6.005.1x+3T2016/block-v1:MITx+6.005.1x+3T2016+type@sequential+block@12-Equality/block-v1:MITx+6.005.1x+3T2016+type@vertical+block@vertical_Questions_4386c462c7bd

Map<String, Integer> a = new HashMap<>(), b = new HashMap<>();
a.put("c", 130); 
b.put("c", 130);

在这个例子中,数值130在编译时的类型为int,而在运行时,130被放入Map中,此时它必须被自动装箱成为Integer类型。

a.get("c").equals(b.get("c"))会返回true,注意到a.get("c")以及b.get("c")返回的是Integer类型,但是使用equals方法比较二者仍返回true

a.get("c") == b.get("c")此时使用==进行引用比较,返回为false

int i = a.get("c");
int j = b.get("c");

此时i==j结果为true。这里a.get("c")b.get("c")返回的Integer类型被自动拆箱成为int类型,再使用==比较显然会返回true

参考

[1] https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html
[2] http://web.mit.edu/6.031/www/sp21/classes/15-equality/#implementing_equals

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值