我想知道这个问题是否可以用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
条件为假)?
答案 0 :(得分:170)
一种简单的方法是使用Float.NaN
:
float x = Float.NaN; // <--
if (x == x) {
System.out.println("Ok");
} else {
System.out.println("Not ok");
}
Not ok
您可以使用Double.NaN
执行相同操作。
来自JLS §15.21.1. Numerical Equality Operators ==
and !=
:
根据IEEE 754标准的规则执行浮点相等测试:
如果任一操作数为NaN,则
==
的结果为false
,但!=
的结果为true
。确实,当且仅当
x!=x
的值为NaN时,测试true
为x
。...
答案 1 :(得分:157)
int x = 0;
if (x == x) {
System.out.println("Not ok");
} else {
System.out.println("Ok");
}
答案 2 :(得分:147)
Java Language Specifications NaN
不等于NaN
。
因此导致x
等于NaN
的任何行都会导致这种情况,例如
double x=Math.sqrt(-1);
来自Java语言规范:
浮点运算符不会产生异常(第11节)。一个手术 溢出产生一个有符号的无穷大,一个操作 下溢产生非规范化值或有符号零,和 没有数学上明确结果的操作会产生NaN。所有 以NaN作为操作数的数值运算会产生NaN。如 已经描述过,NaN是无序的,所以是一个数字比较 涉及一个或两个NaN的操作返回false 和任何!= 涉及NaN的比较返回true,包括x!= x,当x是NaN时。
答案 3 :(得分:72)
不确定这是否是一个选项,但将x
从局部变量更改为字段将允许其他线程在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
答案 4 :(得分:55)
替换后的行可以读取。
double x = Double.NaN;
这会导致打印出来。
Java语言规范(JLS)说:
浮点运算符不会产生异常(第11节)。溢出的操作产生有符号的无穷大,下溢的操作产生非规范化值或带符号的零,并且没有数学定义结果的操作产生NaN。以NaN作为操作数的所有数值运算都会产生NaN。正如已经描述的那样,NaN是无序的,因此涉及一个或两个NaN的数字比较操作返回false,并且涉及NaN的任何!=比较返回true,包括当x是NaN时x!= x。
答案 5 :(得分:30)
我设法从此获得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;
}
}
}
答案 6 :(得分:25)
有很多解决方案:
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");
}
}
}
答案 7 :(得分:25)
一个简单的解决方案是:
System.out.println("Gotcha!");if(false)
if( a == a ){
System.out.println("Not yet...");
} else {
System.out.println("Gotcha!");
}
但我不知道这个谜语的所有规则......
<强>:)强> 我知道这是一个骗子,但不知道所有规则,这是问题的最简单的解决方案:)
答案 8 :(得分:11)
使用System
在同一个包中创建您自己的课程Condition
在这种情况下,您的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");
}
}
}
答案 9 :(得分:9)
使用与其他答案相同的跳过/更改输出方法:
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");
}
}
}