我对Java的方式对待有点混乱==
,并equals()
当它涉及到int
,Integer
和其他类型的数字.例如:
Integer X = 9000;
int x = 9000;
Short Y = 9000;
short y = 9000;
List<Boolean> results = new ArrayList<Boolean>();
// results.add(X == Y); DOES NOT COMPILE 1)
results.add(Y == 9000); // 2)
results.add(X == y); // 3)
results.add(X.equals(x)); // 4)
results.add(X.equals(Y)); // 5)
results.add(X.equals(y)); // 6)
System.out.println(results);
Run Code Online (Sandbox Code Playgroud)
输出(也许你应该先猜测):
[true, true, true, false, false]
Run Code Online (Sandbox Code Playgroud)
X == Y
不能编译是可以预料的,是不同的对象. Y == 9
是true
,鉴于9是默认的int
,并且鉴于1)甚至没有编译.请注意,你不能把int
一个方法放入期望a的方法中Short
,但在这里它们是相同的.x
装箱和Integer
.equal()
.X == y
是true
,但是X.equals(y)
是false
?不应该==
总是比更严格equals()
吗?如果有人能帮助我理解这一点,我会很感激.出于什么原因,==和equals()表现如此?
编辑: 我已将9更改为9000以显示此行为与-128到127之间的整数表现的任何异常方式无关.
2 次编辑: OK,如果你认为你明白这东西,你应该考虑以下内容,只是为了确保:
Integer X = 9000;
Integer Z = 9000;
short y = 9000;
List<Boolean> results = new ArrayList<Boolean>();
results.add(X == Z); // 1)
results.add(X == y); // 2)
results.add(X.equals(Z)); // 3)
results.add(X.equals(y)); // 4)
System.out.println(results);
Run Code Online (Sandbox Code Playgroud)
输出:
[false, true, true, false]
Run Code Online (Sandbox Code Playgroud)
我理解的原因是:
X
unboxed,然后相同的值,如此相等.y
不能盒装到一个Integer
所以不能平等.dfa*_*dfa 22
(小)整数实例被缓存,因此不变的x == y被保留用于小实例(实际上-127 +128,取决于JVM):
Integer a = 10;
Integer b = 10;
assert(a == b); // ok, same instance reused
a = 1024;
b = 1024;
assert(a == b); // fail, not the same instance....
assert(a.equals(b)); // but same _value_
Run Code Online (Sandbox Code Playgroud)
编辑
4)和5)产生错误,因为equals
检查类型:X
是整数而是Y
短.这是java.lang.Integer #equals方法:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
Run Code Online (Sandbox Code Playgroud)
wax*_*ing 12
的原因
X == y
Run Code Online (Sandbox Code Playgroud)
真实与二进制数字促销有关.当等于运算符的至少一个操作数可转换为数字类型时,将使用数字相等运算符.首先,第一个操作数是未装箱的.然后,两个操作数都转换为int
.
而
X.equals(y)
Run Code Online (Sandbox Code Playgroud)
是一个正常的函数调用.如上所述,y
将自动装箱到一个Short
物体.Integer.equals
如果参数不是Integer
实例,则始终返回false .通过检查实现可以很容易地看出这一点.
有人可能会说这是一个设计缺陷.
这个故事的士气:
自动装箱/拆箱令人困惑,类型促销也是如此.它们共同构成了良好的谜语,但却是可怕的代码.
在实践中,使用小于int的数字类型很少有意义,我几乎倾向于配置我的eclipse编译器将所有自动装箱和-unboxing标记为错误.