我想知道这个问题是否可以用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
条件设为假)?
一个简单的方法是使用 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
的值为 NaN 时,测试x!=x
是true
的。。
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)。一个操作 溢出会产生有符号无穷大,该操作 下溢产生非规范化值或有符号零,并且 没有数学上确定结果的操作会产生 NaN。都 结果,以 NaN 作为操作数的数字运算会产生 NaN。如 已经描述过了,NaN是无序的,所以数值比较 涉及一个或两个 NaN 的操作返回 false 和任何 != 涉及 NaN 的比较返回 true,包括 x 为 NaN 时的 x!=x。
不确定这是否是一个选项,但将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;
这将导致打印陷阱。
Java语言规范(JLS)说:
浮点运算符不会产生异常 (§11)。溢出的操作产生有符号无穷大,下溢的操作产生非规范化值或有符号零,没有数学上确定结果的操作产生 NaN。所有以 NaN 为操作数的数字运算都会产生 NaN。如前所述,NaN 是无序的,因此涉及一个或两个 NaN 的数值比较操作返回 false,任何涉及 NaN 的 != 比较返回 true,包括 x 为 NaN 时的 x!=x。
我设法从中得到了一个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;
}
}
}
有很多解决方案:
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");
}
}
}
一个简单的解决方案是:
System.out.println("Gotcha!");if(false)
if( a == a ){
System.out.println("Not yet...");
} else {
System.out.println("Gotcha!");
}
但我不知道这个谜语的所有规则......
:)我知道这是一个作弊,但在不知道所有规则的情况下,这是解决问题的最简单方法吗:)
在同一个包中创建自己的类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");
}
}
}
Ideone DEMO
使用与另一个答案相同的跳过/更改输出方法:
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");
}
}
}
如何在不修改条件本身的情况下跳过第一种情况?
"例如,此类问题中的部分不应误导您。我这边的更多想法:
class Condition1 {
// you can change in the main
public static void main(String[] args) {
int x = 0;
if (x == x) /*{
// the most popular method in actual debug, don't you think?
System.out.println("Ok");
} else */{
System.out.println("Not ok");
}
}
}
class Condition2 {
// you can change in the main
public static void main(String[] args) {
int x = 0;
if (x == x); if (false) {
System.out.println("Ok");
} else {
System.out.println("Not ok");
}
}
}
class Condition3 {
// you can change in the main
public static void main(String[] args) {
System.out.println("Not ok");
}
private void ignored() {
int x = 0;
if (x == x) {
System.out.println("Ok");
} else {
System.out.println("Not ok");
}
}
}
class Condition4 {
// you can change in the main
public static void main(String[] args) {
int x = 0;
if (false) {
return; // this becomes "the first case" and it's skipped
} else {
System.out.println("Not ok");
return;
}
if (x == x) {
System.out.println("Ok");
} else {
System.out.println("Not ok");
}
}
}
import static Condition5.Container.x;
class Condition5 {
static class Container {
static int x = new Inner().hashCode();
}
private static class Inner {
public Inner() {
throw new IllegalStateException();
}
}
public static void main(String[] args) {
try {
{
int x = 0;
}
if (x == x) {
System.out.println("Ok");
} else {
System.out.println("Not ok");
}
} catch (Error e) {
System.out.println("Not ok");
}
}
}