今天在写leetcode时遇到一道题始终过不了,经过排查,问题出现在下面这个方法:
pop()和peek()的返回值都是Integer类型。我在调试时发现,当pop()和peek()返回值明明相等时,if居然判false,导致我的minStack元素没有成功出栈,后面我换了一个写法,想仔细看看pop()返回值到底是什么,如下:
结果,居然通过了!!!
这两个写法的结果应该一样才对啊,为啥第二种写法的逻辑是正确的?
我编写了一个测试类,如下:
public class TestCall {
public static void main(String[] args) {
A a = new A();
B b = new B();
if (a.test1() == b.test1()) {
System.out.println("1=1");
}
if (a.test2() == b.test2()) {
System.out.println("127=127");
}
if (a.test3() == b.test3()) {
System.out.println("12889=12889");
}
}
}
class A {
public Integer test1() {
return 1;
}
public Integer test2() {
return 127;
}
public Integer test3() {
return 12889;
}
}
class B {
public Integer test1() {
return 1;
}
public Integer test2() {
return 127;
}
public Integer test3() {
return 12889;
}
}
只有1=1、127=127输出,第三个正是我测试用例失败的那个数,为啥只有前面两个可以成功输出呢?
先说结论,这其实是Integer的特性及java语法导致的问题。
Integer源码注释里面写了如下这段话:
上面说的是Integer会自动缓存-128~127这些数值的对象,而java的"=="号,如果比较的两边都是引用类型,实际比较的其实是两边的对象地址,当值大于128时,Integer会创建新的对象,所以即使两个Integer对象的值相等,”==“比较的结果也会是false,因为它们是两个对象,这就是12889=12889不能输出的原因。1=1、127=127能输出则是因为缓存,"=="两边的Integer是同一个对象。
回到主题,之所以第二种写法能够运行正常,其实是因为java中的自动拆箱机制,这里不深入讨论,以Integer为例子,只要当二元操作符两边有一个操作数为int,那另一个Integer操作数会被自动拆箱为int值,所以第二种写法中的if中比较的是值,不是对象,因此逻辑正确。
如果遇到相同问题,希望这篇文章能帮到你!