我在编写测试时今天有一种奇怪的情况。基本上,我有一个数据类。让我们说玩具,例如,我们可以从中检索一个名称:
public class Toy {
private String name;
public Toy(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
我有一个例外,它的工作方式类似于此(例如,只显示我们在它变坏之前所有工作的数据);我还包括一个主要用于测试目的:
public class ToyFactoryException extends Exception {
public ToyFactoryException(Toy firstToy, Toy secondToy) {
super("An error occurred when manufacturing: " +
"\nfirstToy: " + firstToy != null ? firstToy.getName() : null +
"\nsecondToy: " + secondToy != null ? secondToy.getName() : null);
}
public static void main(String[] args) {
try {
throw new ToyFactoryException(null, new Toy("hi"));
} catch (ToyFactoryException myException) {
System.out.println("It should be there.");
} catch (Exception exception) {
System.out.println("But it's there instead.");
}
}
}
正如我在第一个catch块中写的那样,异常应该在ToyFactoryException中捕获。
但是,在异常中,它试图在这里读取firstToy.getName():firstToy != null ? firstToy.getName() : null
firstToy != null
应评估为false,这意味着它不应该首先尝试调用firstToy.getName()
。当您以相反的顺序写它时:
public ToyFactoryException(Toy firstToy, Toy secondToy) {
super("An error occurred when manufacturing: " +
"\nfirstToy: " + firstToy != null ? null : firstToy.getName() +
"\nsecondToy: " + secondToy != null ? secondToy.getName() : null);
}
你意识到它现在读取null
,这意味着它真正读取firstToy != null
为真。
如果你用这种方式编写main(null是构造函数的第二个参数):
public static void main(String[] args) {
try {
throw new ToyFactoryException(new Toy("hi"), null);
} catch (ToyFactoryException myException) {
System.out.println("It should be there.");
} catch (Exception exception) {
System.out.println("But it's there instead.");
}
}
它运作正常,尽管secondToy三元条件的编写方式与firstToy三元相同。
为什么firstToy上的三元条件不能正确评估null?
你应该在条件表达式周围加上括号。
这个:
"string " + firstToy != null ? firstToy.getName() : null
意思是:
("string " + firstToy) != null ? firstToy.getName() : null
你需要这个:
"string " + (firstToy != null ? firstToy.getName() : null)