一个Javavariables如何可以不同于自己?

我想知道这个问题是否可以在Java中解决(我是新的语言)。 这是代码:

class Condition { // you can change in the main public static void main(String[] args) { int x = 0; if (x == x) { System.out.println("Ok"); } else { System.out.println("Not ok"); } } } 

我在实验室中收到以下问题:如何在不修改条件本身的情况下跳过第一种情况(即使x == x条件为false)?

一个简单的方法是使用Float.NaN

 float x = Float.NaN; // <-- if (x == x) { System.out.println("Ok"); } else { System.out.println("Not ok"); } 
不好

你可以用Double.NaN来做同样的Double.NaN


来自JLS§15.21.1。 数值相等运算符==!=

浮点平等testing按照IEEE 754标准的规则进行:

  • 如果两个操作数都是NaN,那么==的结果是false但是!=的结果是true

    事实上,当且仅当x的值是NaN时,testingx!=x才是true

 int x = 0; if (x == x) { System.out.println("Not ok"); } else { System.out.println("Ok"); } 

按照Java语言规范, NaN不等于NaN

因此,任何导致x等于NaN都会导致这种情况,比如

 double x=Math.sqrt(-1); 

来自Java语言规范:

浮点运算符不会产生任何exception(§11)。 溢出的操作产生有符号的无穷大,下溢的操作产生非规格化的值或有符号的零,而没有math上确定的结果的操作产生NaN。 以NaN作为操作数的所有数字操作都会产生NaN。 如前所述,NaN是无序的,所以涉及一个或两个NaN的数字比较操作返回false ,任何!=涉及NaN的比较都返回true,当x是NaN时,包括x!= x。

不知道这是否是一个选项,但将x从本地variables更改为字段将允许其他线程更改if语句中左侧和右侧之间的值。

这里是简短的演示:

 class Test { static int x = 0; public static void main(String[] args) throws Exception { Thread t = new Thread(new Change()); t.setDaemon(true); t.start(); while (true) { if (x == x) { System.out.println("Ok"); } else { System.out.println("Not ok"); break; } } } } class Change implements Runnable { public void run() { while (true) Test.x++; } } 

输出:

 ⋮ Ok Ok Ok Ok Ok Ok Ok Ok Not ok 

被replace的行可以读取。

 double x = Double.NaN; 

这会导致打印错误。

Java语言规范(JLS)说:

浮点运算符不会产生任何exception(§11)。 溢出的操作产生有符号的无穷大,下溢的操作产生非规格化的值或有符号的零,而没有math上确定的结果的操作产生NaN。 以NaN作为操作数的所有数字操作都会产生NaN。 如前所述,NaN是无序的,所以涉及一个或两个NaN的数字比较操作返回false,任何!=涉及NaN的比较都返回true,当x是NaN时,包括x!= x。

我设法得到了一个Gotcha! 由此:

 volatile Object a = new Object(); class Flipper implements Runnable { Object b = new Object(); public void run() { while (true) { Object olda = a; a = b; a = olda; } } } public void test() { new Thread(new Flipper()).start(); boolean gotcha = false; while (!gotcha) { // I've added everything above this - I would therefore say still legal. if (a == a) { System.out.println("Not yet..."); } else { System.out.println("Gotcha!"); // Uncomment this line when testing or you'll never terminate. //gotcha = true; } } } 

有这么多的解决scheme:

 class A extends PrintStream { public A(PrintStream x) {super(x);} public void println(String x) {super.println("Not ok");} public static void main(String[] args) { System.setOut(new A(System.out)); int x = 0; if (x == x) { System.out.println("Ok"); } else { System.out.println("Not ok"); } } } 

一个简单的方法是:

 System.out.println("Gotcha!");if(false) if( a == a ){ System.out.println("Not yet..."); } else { System.out.println("Gotcha!"); } 

但我不知道这个谜语的所有规则

🙂我知道这是一个骗子,但不知道所有规则,这是问题的最简单的解决scheme:)

Condition相同的包中创build自己的类System
在这种情况下,你的System类将隐藏java.lang.System

 class Condition { static class System { static class out { static void println(String ignored) { java.lang.System.out.println("Not ok"); } } } public static void main (String[] args) throws java.lang.Exception { int x = 0; if (x == x) { System.out.println("Not ok"); } else { System.out.println("Ok"); } } } 

Ideone DEMO

使用与其他跳转/更改输出方法相同的答案:

 class Condition { public static void main(String[] args) { try { int x = 1 / 0; if (x == x) { System.out.println("Ok"); } else { System.out.println("Not ok"); } } catch (Exception e) { System.out.println("Not ok"); } } }