一个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"); } } }