ChatGPT解决这个技术问题 Extra ChatGPT

How can a Java variable be different from itself?

I am wondering if this question can be solved in Java (I'm new to the language). This is the code:

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

I received the following question in my lab: How can you skip the first case (i.e. make the x == x condition false) without modifying the condition itself?

I believe there should be more restriction, otherwise it is too open.
Is it as simple as System.out.println("Gotcha!"); instead of the comment? :)
Good, then is double a= Double.NaN the shortest answer and my "hack is just a cheat ;)
This is cute Java trivia, but I hope no one will consider making it an interview question. People considering candidates for employment should be doing the best they can to figure out if the candidate understands programming, not how much trivia he's accumulated. I've barely used floating point numbers in 17 years of programming in Java, much less the NaN construct, MUCH less knowing how it behaves with the == operator...
@user1158692 Matter of opinion, I personally hate any programs where the basic operators have been overridden and am glad that any code I recieve in java hasn't been messed with (I have seen * overridden as the vector cross product and the dot product because both are kinds of vector multiplication; infuriating! Whereas in java one is called .cross() and the other is .dot() and there is no confusion. Also the fact that "override the == operator and always return false" can't happen seems pro java

C
Community

One simple way is to use Float.NaN:

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

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

You can do the same with Double.NaN.

From JLS §15.21.1. Numerical Equality Operators == and !=:

Floating-point equality testing is performed in accordance with the rules of the IEEE 754 standard: If either operand is NaN, then the result of == is false but the result of != is true. Indeed, the test x!=x is true if and only if the value of x is NaN. ...


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

Heh, this totally answers the question as asked.
@AswinMurugesh Right, but if we are taking the question completely literally as this answer does, then we can delete the else altogether. This wouldn't technically violate the terms of the question.
Considering this is my second highest voted answer I'm not sure whether to conclude that I'm very funny or a crappy programmer.
@JeroenVannevel Given the requirements, I think this is the most KISS/YAGNI/appropriate answer ;)
@jddsantaella: obviously this was edited afterwards. The original question said "How can I print 'not ok'".
R
Richard Tingle

By the Java Language Specifications NaN is not equal to NaN.

Therefore any line that caused x to be equal to NaN would cause this, such as

double x=Math.sqrt(-1);

From the Java Language Specifications:

Floating-point operators produce no exceptions (§11). An operation that overflows produces a signed infinity, an operation that underflows produces a denormalized value or a signed zero, and an operation that has no mathematically definite result produces NaN. All numeric operations with NaN as an operand produce NaN as a result. As has already been described, NaN is unordered, so a numeric comparison operation involving one or two NaNs returns false and any != comparison involving NaN returns true, including x!=x when x is NaN.


@sᴜʀᴇsʜᴀᴛᴛᴀ A fair point, I was so busy going off to find said "coding convention" that I forgot to actually answer the question
This is only valid if a is declared as Object or double.
@ChristianKuetbach True, in the absence of any information to the contrary I have assumed the commented out line can be anything
Even my cheated answer is correct and fulfills the rules. I edited only before the if-statement and only "Gotcha! is printed out. I'am sure, that this answer is not the answer in the mind of the creator of this riddle. But the riddle is not well defined (as most softwareprojects).
n
naXa stands with Ukraine

Not sure if this is an option but changing x from local variable to a field would allow other thread to change its value between the reading left and right side in if statement.

Here is short demo:

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++;
    }
}

Output:

⋮
Ok
Ok
Ok
Ok
Ok
Ok
Ok
Ok
Not ok

Haha +1 for effort, but man...there's no way anyone in my Java lab would have come up with something like this (instructor included).
@WilliamGaul Really? I always though that it is one of basic examples showing possible problems with multithreading and why people who think that this subject is easy should never be in charge of anything :)
C
Cole Tobin

The replaced line could read.

double x = Double.NaN;

This would cause the gotcha to be printed.

Java Language Specification (JLS) says:

Floating-point operators produce no exceptions (§11). An operation that overflows produces a signed infinity, an operation that underflows produces a denormalized value or a signed zero, and an operation that has no mathematically definite result produces NaN. All numeric operations with NaN as an operand produce NaN as a result. As has already been described, NaN is unordered, so a numeric comparison operation involving one or two NaNs returns false and any != comparison involving NaN returns true, including x!=x when x is NaN.


Or lead into a compile error, if a is declared as String a = "Nope"; That why I asked for the type of 'a'
The code above gives no information about types, therefore I have made the assumption that a is not already defined.
I think that your answer is the answer, that was in the mind of the riddle creator. But the rules were not clear. Only two rules were given: 1. only insert in the line with the comment and 2. only get one "Gotcha! printed out.
the riddle author could have made always valid by surrounding the code in { }
O
OldCurmudgeon

I managed to get a Gotcha! from this:

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

This changes more than just the comment as the question asks for.
I've tried something like that that but I think that it's guaranteed that it will produce the same result always, isn't it?
@Mex - It does indeed but it preserves enough of the original to demonstrate a further key point that sometimes a != a because it was changed by another thread. I suspect this would win points in an interview.
This is actually quite clever though, I assume this works by "hoping" that a is altered by the first thread in-between the first and second access for comparison
Re your doubters; it's worth noting that everything you've written above the key if statement could be written in a single horrible line if necessary
A
Arvind Kumar Avinash

There are so many solutions:

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

Unless I'm missing something, that super.println should be "Not ok", right?
@Izkata Yes, didn't recheck what the desired output should be.
C
Christian Kuetbach

One easy solution is:

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

But I don't know all the rules to this riddle...

:) I know that this is a cheat, but without knowing all rules, is this the easiest solution to the question :)


Can be written in one line ;)
@ChristianKuetbach As can all programs
@ChristianKuetbach In all fairness the compiler should immediately delete all files on your computer if you tried to actually program like that
Why make it so difficult? if (System.out.println("Gotcha") && false)
error: 'void' type not allowed here if(System.out.println("Gotcha")&& false) Your code won't compile...
I
Ilya

Create your own class System in tha same package with Condition.
In this case your System class will hide java.lang.System class

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


h
higuaro

Using the same skip/change output approach from another answers:

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