为什么这个程序在第一个print语句中打印为false而在print语句中为true。 i和i1是两个不同的对象,因此第一个语句必须打印" true",这是预期的,但第二个print语句打印" false"这造成了混乱。
public static void main(String[] args) {
Integer i = new Integer(10);
Integer i1 = new Integer(10);
System.out.println(i == i1); //printing false
i++;
i1++;
System.out.println(i == i1);//printing true
}
答案 0 :(得分:5)
使用new
关键字始终会创建两个不同的实例。所以以下情况总是如此:
new Integer(10) != new Integer(10)
因此第一行打印“假”。
然后:
i++;
隐藏拆箱和装箱。它相当于:
i = Integer.valueOf(i.intValue() + 1);
如the Javadoc of Integer.valueOf
中所述,缓存了从-128到127(至少)的值:您正在为Integer.valueOf(11)
和{{1}取回i++
的缓存实例},因此第二行打印“true”。
答案 1 :(得分:1)
下面:
Integer i = new Integer(10);
Integer i1 = new Integer(10);
你要求动态分配两个Integer类类型的实例,这会给你两个不同的引用。如果您将其更改为:
Integer i = 10;
Integer i1 = 10;
然后i和i1的引用将是相等的,因为对于小值,包装类使用缓存的对象。
此:
i++;
i1++;
解释如下:JLS中的15.14.2. Postfix Increment Operator ++(强调我的):
在添加之前,对值1和变量的值执行 二进制数字提升(第5.6.2节) 。如有必要,在存储之前,通过缩小的基元转换(第5.1.3节) *和/或经过装箱转换(第5.1.7节)来缩小总和到变量的类型。
下面的注释也很重要,它表示在应用运算符之前,可能会发生拆箱转换:
请注意,上面提到的二进制数字促销可能包括拆箱转换(第5.1.8节)和价值集转换(第5.1.13节)。如有必要,在将值存储在变量中之前,将值集转换应用于总和。 所以这意味着它被装箱回到包装类型
所以最后在将operator ++应用于分配的Integer实例的引用类型或盒装的Integer类之后,如果其值在盒装类型的正确范围内,则以盒装的Integer结束。
答案 2 :(得分:0)
首先是参考比较,因此得到假,第二个是值比较(在递增时,它是未加框到原始int,因此递增到11并再次自动加框;对于i1相同)。第二个电话是(11 == 11)因此是真的。
答案 3 :(得分:-1)
Integer类有许多其他类实现了equals方法。您可以像这样轻松地比较两个Integer实例:
Integer int1 = new Integer(2);
Integer int2 = new Integer(2);
if(int2.equals(int1)) {
// true
}
考虑在所有您自己的实体/ dtos中实现equals方法:
class Car {
private String color;
private Integer model;
public Car(String color, Integer model) {
this.color = color;
this.model = model;
}
public String getColor() { return color; }
public Integer getModel() { return model; }
@Override
public boolean equals(final Object obj) {
if(this == obj) {
return true; // You are actually comparing the same instances
}
if(obj instanceof Car) { // Now you know both obj are instances of class Car
final Car other = (Car) obj; // Safe to cast
return Objects.equal(color, other.getColor())
&& Objects.equal(model, other.getModel()
;
}
return false;
}
}