Java变量如何与自身不同?

时间:2013-10-17 01:15:23

标签: java if-statement

我想知道这个问题是否可以用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条件为假)?

10 个答案:

答案 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时,测试truex

  •   
     

...

答案 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");
        }
    }
}  

Ideone DEMO

答案 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");
        }
    }
}