英語 - java if 文 まとめる




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

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

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

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

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

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


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です。

...


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

イデオンデモ


これがオプションであるかどうかはわかりませんが、 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

私は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;
    }
  }
}

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

double x = Double.NaN;

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

Java言語仕様(JLS)によると:

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


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






if-statement