이 질문을 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로 설정) 어떻게해야합니까?
답변
한 가지 간단한 방법은 다음을 사용하는 것입니다 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이면의 결과
==
는false
이지만 결과는!=
입니다true
.실제로 테스트
x!=x
는true
의 값x
이 NaN 인 경우에만 수행됩니다 .…
답변
int x = 0;
if (x == x) {
System.out.println("Not ok");
} else {
System.out.println("Ok");
}
답변
에 의해 Java 언어 사양 NaN
과 동일하지 않습니다 NaN
.
따라서 다음과 같이 x
같게 된 모든 줄은 NaN
다음과 같이 발생합니다.
double x=Math.sqrt(-1);
Java 언어 사양에서 :
부동 소수점 연산자는 예외를 생성하지 않습니다 (§11). 오버플로하는 연산은 부호있는 무한대를 생성하고 언더 플로하는 연산은 비정규 화 된 값 또는 부호있는 0을 생성하며, 수학적으로 명확한 결과가없는 연산은 NaN을 생성합니다. NaN을 피연산자로 사용하는 모든 숫자 연산은 결과로 NaN을 생성합니다. 이미 설명했듯이 NaN은 순서가 지정되지 않았으므로 하나 또는 두 개의 NaN을 포함하는 숫자 비교 연산은 false를 반환 하고 NaN을 포함하는 모든! = 비교는 x가 NaN 일 때 x! = x를 포함하여 true를 반환합니다.
답변
이것이 옵션인지 확실하지 않지만 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
답변
교체 된 줄을 읽을 수 있습니다.
double x = Double.NaN;
이로 인해 gotcha가 인쇄됩니다.
JLS (Java Language Specification)는 다음과 같이 말합니다.
부동 소수점 연산자는 예외를 생성하지 않습니다 (§11). 오버플로하는 연산은 부호있는 무한대를 생성하고 언더 플로하는 연산은 비정규 화 된 값 또는 부호있는 0을 생성하며, 수학적으로 명확한 결과가없는 연산은 NaN을 생성합니다. NaN을 피연산자로 사용하는 모든 숫자 연산은 결과로 NaN을 생성합니다. 이미 설명했듯이 NaN은 순서가 지정되지 않았으므로 하나 또는 두 개의 NaN을 포함하는 숫자 비교 연산은 false를 반환하고 NaN을 포함하는 모든! = 비교는 x가 NaN 일 때 x! = x를 포함하여 true를 반환합니다.
답변
나는 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");
}
}
}