108

この質問を 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 にする) にはどうすればよいですか?

4

10 に答える 10

174

簡単な方法の 1 つは、次を使用することFloat.NaNです。

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

if (x == x) {
    System.out.println("Ok");
} else {
    System.out.println("Not ok");
}
良くないですよ

で同じことができますDouble.NaN


JLS §15.21.1 より==!=数値等値演算子:

浮動小数点の等価性テストは、IEEE 754 標準の規則に従って実行されます。

  • いずれかのオペランドが NaN の場合、 is の結果は==isfalseの結果になり!=ますtrue

    実際、テストx!=xはの値が NaNtrueである場合にのみ行われます。x

...

于 2013-10-17T01:17:22.797 に答える
159
int x = 0;
if (x == x) {
    System.out.println("Not ok");
} else {
    System.out.println("Ok");
}
于 2013-10-17T01:18:30.373 に答える
147

Java 言語仕様 により、NaNは と等しくありませんNaN

したがって、次のxように等しいとなる行NaNは、これを引き起こします。

double x=Math.sqrt(-1);

Java 言語仕様から:

浮動小数点演算子は例外を生成しません (§11)。オーバーフローする演算は符号付き無限大を生成し、アンダーフローする演算は非正規化値または符号付きゼロを生成し、数学的に明確な結果を持たない演算は NaN を生成します。オペランドとして NaN を使用するすべての数値演算は、結果として NaN を生成します。既に説明したように、NaN は順序付けされていないため、1 つまたは 2 つの NaN を含む数値比較演算は falseを返し、NaN を含む != 比較は true を返します (x が NaN の場合の x!=x を含む)。

于 2013-12-04T12:02:25.820 に答える
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++;
    }
}

出力:

⋮
Ok
Ok
Ok
Ok
Ok
Ok
Ok
Ok
Not ok
于 2013-10-17T01:45:39.663 に答える
56

置き換えられた行は読み取ることができました。

double x = Double.NaN;

これにより、落とし穴が印刷されます。

Java 言語仕様 (JLS) は次のように述べています。

浮動小数点演算子は例外を生成しません (§11)。オーバーフローする演算は符号付き無限大を生成し、アンダーフローする演算は非正規化値または符号付きゼロを生成し、数学的に明確な結果を持たない演算は NaN を生成します。オペランドとして NaN を使用するすべての数値演算は、結果として NaN を生成します。既に説明したように、NaN は順序付けされていないため、1 つまたは 2 つの NaN を含む数値比較演算は false を返し、NaN を含む != 比較は true を返します (x が NaN の場合の x!=x を含む)。

于 2013-12-04T12:06:50.777 に答える
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;
    }
  }
}
于 2013-12-04T12:21:44.877 に答える
26

非常に多くの解決策があります:

import java.io.PrintStream;

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");
        }
    }
}
于 2013-10-17T18:35:31.957 に答える
25

1 つの簡単な解決策は次のとおりです。

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

しかし、私はこのなぞなぞのすべてのルールを知っているわけではありません...

:) これがチートであることは知っていますが、すべてのルールを知らなくても、これが質問に対する最も簡単な解決策ですか:)

于 2013-12-04T12:09:26.847 に答える
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");
        }
    }
}  

イデオネデモ

于 2013-11-04T19:52:05.387 に答える