如何声明 i 和 j 使其成为一个无限循环?

23
while( i <= j && i >= j && i != j) {}

如何声明i和j使其成为无限循环?

// 这是我遇到的一道面试题。

问题要求给出i和j的声明,使其始终为真。

我无法通过将i和j声明为数字类型来解决这个问题。还有哪些类型可以满足条件?


@DJClayworth 你说的“||版本”是什么意思? - Matt Ball
@ Alan,非常好的问题 +1 - ELAYARAJA
3个回答

41
Integer i=new Integer(1000);
Integer j=new Integer(1000);

System.out.println((i<=j)+" "+(i>=j)+" "+(i!=j));

ij 会在使用 <=>= 进行比较时自动拆箱为 int,但不会在使用 != 时自动拆箱。虽然 ij 是不同的实例,但它们具有相同的整型值。这就是为什么这三个比较操作都返回 true 的原因。


2
不错,我认为这是正确的答案。至少它返回了true。// 真是一个棘手的面试问题!!! - Alan
1
+1 i <= j && i >= j && i != j 在这种情况下评估为true - Martin Smith
1
+1 分钟给准确答案,但为什么 i 和 j 在 i!=j 时不会被取消装箱?难道 i!=j 不应该检查 i 和 j 的值吗?还有哪些语言也是这样的情况? - SpeedBirdNine
1
@SpeedBirdNine,否则无法执行i!=null。有时您想比较实例而不是值。 - Piotr Praszmo
1
@SpeedBirdNine 更重要的是,对于整数 i 和 j,i!=j 已经是有效的代码,对于不同的对象返回 false。对于 Java 来说,添加到语言中的内容不能改变现有代码的行为非常重要。 - DJClayworth

3

这个方式也有效(“在我的机器上”):

Integer a = 128, b = 128;

然而,这样做是行不通的:

Integer a = 127, b = 127;

自动装箱一个int是对Integer.valueOf(int)的调用的语法糖。此函数使用一个缓存来存储-128到127(包括)之间的值。它可能缓存其他值,但在我的情况下没有缓存。
因此,赋值128没有命中缓存;每次自动装箱操作都会创建一个新的Integer实例,并且引用比较a!= b为真。赋值127有缓存命中,并且生成的Integer对象实际上是来自缓存的同一实例。因此,引用比较a!= b为假。
我真正想指出的是要注意使用自动装箱进行引用比较。更有可能的现实问题是你认为a == b为真,因为它们被分配了相同的(自动装箱的)值,您运行一些单元测试来确认您的期望,然后在一些计数器超过缓存上限时您的代码在实际开发中失败。有趣的时刻!

+1 很好的补充Banthar的回答! - Wolf

-2
任何相等的“i”和“j”的值都将根据给定的语句显示为true,例如:
Integer i = new Integer(1);
Integer j = new Integer(1);

while( i <= j && i >= j && i != j) {}

魔法在于使用运算符!对于!=运算符,编译器将操作数视为对象(包括它们的值),而对于>=或<=运算符,编译器仅将操作数的值视为重要。因此,上述语句返回true。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接