Java变量如何与自身不同?

Hus*_*sam 106 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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

ars*_*jii 170

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

float x = Float.NaN;  // <--

if (x == x) {
    System.out.println("Ok");
} else {
    System.out.println("Not ok");
}
Run Code Online (Sandbox Code Playgroud)
Not ok

你也可以这样做Double.NaN.


来自JLS§15.21.1.数值等式运算符==!=:

根据IEEE 754标准的规则执行浮点相等性测试:

  • 如果任一操作数是NaN,则结果==false但是结果!=true.

    实际上,测试x!=xtrue当且仅当值为xNaN时.

...


Jer*_*vel 157

int x = 0;
if (x == x) {
    System.out.println("Not ok");
} else {
    System.out.println("Ok");
}
Run Code Online (Sandbox Code Playgroud)

  • 考虑到这是我的第二高投票答案,我不确定是否可以断定我是非常有趣或者是一个蹩脚的程序员. (67认同)
  • 嘿,这完全回答了问题. (62认同)
  • @jddsantaella:显然这是后来编辑的.最初的问题是"如何打印'不行''". (12认同)
  • @AswinMurugesh对,但如果我们按照这个答案完全按字面意思提问,那么我们就可以完全删除`else`.这在技术上不会违反问题的条款. (5认同)
  • @JeroenVannevel根据要求,我认为这是最KISS/YAGNI /适当的答案;) (5认同)
  • @arshajii:如果if之后有一个分号,那么else部分会出错. (4认同)
  • 问题是"你怎么能跳过第一个案例",所以这个答案是错误的. (3认同)
  • 好吧,如果你采取这条路径然后只是在`if`之后放一个`;`并直接打印`'Not ok"`.但是我不相信这是OP所追求的. (2认同)
  • 解决问题不是编程.你赢了,因为你解决了这个问题,改变了观点,我认为这是预期的答案.+1 (2认同)
  • 您忘记了最重要的最后一行:“// yourQuestion == PWND!” (2认同)

Ric*_*gle 147

Java语言规范 NaN不等于NaN.

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

double x=Math.sqrt(-1);
Run Code Online (Sandbox Code Playgroud)

从Java语言规范:

浮点运算符不会产生例外(第11节).溢出的操作产生有符号的无穷大,下溢的操作产生非规范化值或带符号的零,并且没有数学定义结果的操作产生NaN.以NaN作为操作数的所有数值运算都会产生NaN.如已经描述的那样,NaN是无序的,因此涉及一个或两个NaN的数字比较操作返回false,并且涉及NaN的任何!=比较返回true,包括当x是NaN时x!= x.

  • 即使我被骗的答案也是正确的并且符合规则.我只在if语句之前进行了编辑,只打印了"Gotcha!".我确信,这个答案不是这个谜语创造者心中的答案.但是这个谜语没有明确定义(因为大多数软件项目都是如此) ). (2认同)

Psh*_*emo 73

不确定这是否是一个选项,但是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++;
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

?
Ok
Ok
Ok
Ok
Ok
Ok
Ok
Ok
Not ok
Run Code Online (Sandbox Code Playgroud)

  • @WilliamGaul真的吗?我总是认为它是显示多线程可能存在问题的基本示例之一,以及为什么认为这个主题很容易的人永远不应该负责任何事情:) (28认同)
  • 哈哈+1努力,但是男人......我的*Java实验室里的任何人都不会想出这样的东西(包括教练). (8认同)
  • 在我读完你的答案之前,我甚至没有考虑过这个问题.感谢您将此添加到我的mental toolkit :) (4认同)

小智 55

更换的行可以读取.

double x = Double.NaN;
Run Code Online (Sandbox Code Playgroud)

这将导致打印出来.

Java语言规范(JLS)说:

浮点运算符不会产生例外(第11节).溢出的操作产生有符号的无穷大,下溢的操作产生非规范化值或带符号的零,并且没有数学定义结果的操作产生NaN.以NaN作为操作数的所有数值运算都会产生NaN.如已经描述的那样,NaN是无序的,因此涉及一个或两个NaN的数字比较操作返回false,并且涉及NaN的任何!=比较返回true,包括当x是NaN时x!= x.


Old*_*eon 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;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

  • @Mex - 它确实存在,但它保留了足够的原始内容来演示另一个关键点,有时候`a!= a`因为它被另一个线程改变了.我怀疑这会在采访中赢得积分. (4认同)
  • 你的怀疑者; 值得注意的是,如果有必要,你在密钥"if"语句之上写的所有内容都可以写成一条可怕的行. (4认同)

Joh*_*uhn 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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 绝对精彩! (2认同)

Chr*_*ach 25

一个简单的解决方案是

System.out.println("Gotcha!");if(false)
if( a == a ){
  System.out.println("Not yet...");
} else {
  System.out.println("Gotcha!");
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • @ChristianKuetbach所有节目都可以 (6认同)
  • 错误:此处不允许使用'void'类型(System.out.println("Gotcha")&& false)您的代码将无法编译... (3认同)
  • @ChristianKuetbach公平地说,如果您尝试实际编程,编译器应立即删除计算机上的所有文件 (2认同)

Ily*_*lya 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");
        }
    }
}  
Run Code Online (Sandbox Code Playgroud)

Ideone DEMO


hig*_*aro 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");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)