我遇到了这个问题,我试图找出答案。
这是问题:
假定线程环境,并且不了解其他任何信息,myMethod()的潜在问题是什么?我们如何以最简单的方式解决它?
myMethod
有什么问题?
public class DummyTest {
private static final String FUBAR = "fubar";
public boolean myMethod(final MyObject bar) {
if (bar.getFoo() != null) {
return bar.getFoo().equals(FUBAR);
} else {
return false;
}
}
public interface MyObject {
String getFoo();
void setFoo(String o);
}
}
您正在检查bar.getFoo()
两次,这在多线程环境中可能会有不同的结果。 MyObject
是一个接口,其方法无法同步。
您还需要为bar
添加空检查,并且如果您更改代码,也不需要为bar.getFoo()
空检查(请参阅下文)
您可以用一种衬里方法代替:
return bar != null && FUBAR.equals(bar.getFoo());
或使用三元条件运算符
return bar == null ? false : FUBAR.equals(bar.getFoo());
((除了bar
可能为空)。
可能,bar.getFoo()
可能在多次调用时返回不同的值。
仅阅读一次;并以null安全的方式检查是否与FUBAR
相等:
return Objects.equals(bar.getFoo(), FUBAR);
// or
return FUBAR.equals(bar.getFoo());
[很明显bar
可能为null,但对bar.getFoo()
的双重调用是有问题的。如果我们假设其他线程正在运行,则两次调用bar.getFoo()
之间的bar可能会更改,并返回两个不同的字符串。
一种解决方案是只调用bar.getFoo()
一次并将返回的String
保存为局部变量。
public boolean myMethod(final MyObject bar) {
if (bar == null)
return false;
String foo = bar.getFoo();
if (foo != null) {
return foo.equals(FUBAR);
} else {
return false;
}
}
bar.getFoo()
可能为每个调用返回不同的值。