Java変数はどのようにしてそれ自身と異なることができますか?




java if 文 まとめる (8)

私はこの質問が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にします)。


私はGotcha!を手に入れました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;
    }
  }
}

非常に多くのソリューションがあります:

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

int x = 0;
if (x == x) {
    System.out.println("Not ok");
} else {
    System.out.println("Ok");
}

Condition同じパッケージに独自のクラスSystem作成します。
この場合、 Systemクラスはjava.lang.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");
        }
    }
}  

イデオンデモ


1つの簡単な方法は、 Float.NaNを使用すること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より。 数値平等演算子==!=

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

  • いずれかのオペランドがNaNの場合、 ==の結果はfalseが、 !=の結果はtrueです。

    実際、 x!=xの値がNaNの場合にのみ、 x!=xテストはtrueです。

...


1つの簡単なソリューションは次のとおりです。

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

しかし、私はこの謎にすべてのルールを知らない...

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


Java言語仕様 By NaNNaNと等しくありません。

したがって、 xNaNと等しくする行は、次のようになります。

double x=Math.sqrt(-1);

Java言語仕様から:

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


別の回答から同じスキップ/変更出力アプローチを使用する:

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




if-statement