我使用x!=null以避免NullPointerException。还有其他选择吗?
if (x != null) {
// ...
}
我使用x!=null以避免NullPointerException。还有其他选择吗?
if (x != null) {
// ...
}
当前回答
在Java中避免空检查的最佳方法是正确处理和使用异常。在我的经验中,随着您向前端移动,空检查变得越来越常见和必要,因为它更接近于通过UI提供无效信息的用户(例如,没有值,为字段提交)。
有人可能会争辩说,你应该能够控制UI正在做什么,以免你忘记大多数UI是通过某种类型的第三方库完成的,例如,根据情况或库的不同,它可能会为空白文本框返回NULL或空字符串。
您可以这样组合这两者:
try
{
myvar = get_user_supplied_value();
if (myvar == null || myvar.length() == 0) { alert_the_user_somehow(); return; };
process_user_input(myvar);
} catch (Exception ex) {
handle_exception(ex);
}
人们采取的另一种方法是:
if (myvar && myvar.length() > 0) { };
你也可以抛出一个异常(这是我更喜欢的)
if (myvar == null || myvar.length() == 0) {
throw new Exception("You must supply a name!");
};
但这取决于你。
其他回答
仅适用于这种情况-
在调用equals方法之前不检查变量是否为空(下面的字符串比较示例):
if ( foo.equals("bar") ) {
// ...
}
如果foo不存在,将导致NullPointerException。
如果这样比较字符串,可以避免这种情况:
if ( "bar".equals(foo) ) {
// ...
}
在Java8 lambdas中,可以定义以近乎完美的方式处理嵌套空检查的util方法。
void example() {
Entry entry = new Entry();
// This is the same as H-MANs solution
Person person = getNullsafe(entry, e -> e.getPerson());
// Get object in several steps
String givenName = getNullsafe(entry, e -> e.getPerson(), p -> p.getName(), n -> n.getGivenName());
// Call void methods
doNullsafe(entry, e -> e.getPerson(), p -> p.getName(), n -> n.nameIt());
}
/** Return result of call to f1 with o1 if it is non-null, otherwise return null. */
public static <R, T1> R getNullsafe(T1 o1, Function<T1, R> f1) {
if (o1 != null) return f1.apply(o1);
return null;
}
public static <R, T0, T1> R getNullsafe(T0 o0, Function<T0, T1> f1, Function<T1, R> f2) {
return getNullsafe(getNullsafe(o0, f1), f2);
}
public static <R, T0, T1, T2> R getNullsafe(T0 o0, Function<T0, T1> f1, Function<T1, T2> f2, Function<T2, R> f3) {
return getNullsafe(getNullsafe(o0, f1, f2), f3);
}
/** Call consumer f1 with o1 if it is non-null, otherwise do nothing. */
public static <T1> void doNullsafe(T1 o1, Consumer<T1> f1) {
if (o1 != null) f1.accept(o1);
}
public static <T0, T1> void doNullsafe(T0 o0, Function<T0, T1> f1, Consumer<T1> f2) {
doNullsafe(getNullsafe(o0, f1), f2);
}
public static <T0, T1, T2> void doNullsafe(T0 o0, Function<T0, T1> f1, Function<T1, T2> f2, Consumer<T2> f3) {
doNullsafe(getNullsafe(o0, f1, f2), f3);
}
class Entry {
Person getPerson() { return null; }
}
class Person {
Name getName() { return null; }
}
class Name {
void nameIt() {}
String getGivenName() { return null; }
}
(这个答案首先发布在这里。)
!=的另一种选择空检查是(如果你无法在设计上摆脱它):
Optional.ofNullable(someobject).ifPresent(someobject -> someobject.doCalc());
or
Optional.ofNullable(someobject).ifPresent(SomeClass::doCalc);
SomeClass是某个对象的类型。
但是,您无法从doCalc()获取返回值,因此仅对void方法有用。
您可以为对象和字符串创建一个通用方法,以便在应用程序中完全使用它-这可以帮助您和您的同事:创建一个类,例如StringUtilities,并添加方法,例如getNullString
public static String getNullString(Object someobject)
{
if(null==someobject )
return null;
else if(someobject.getClass().isInstance("") &&
(((String)someobject).trim().equalsIgnoreCase("null")||
((String)someobject).trim().equalsIgnoreCase("")))
return null;
else if(someobject.getClass().isInstance(""))
return (String)someobject;
else
return someobject.toString().trim();
}
简单地将此方法称为,
if (StringUtilities.getNullString(someobject) != null)
{
//Do something
}
我喜欢Nat Pryce的文章。以下是链接:
用多态调度避免空值避免使用“告诉,不要问”风格的null
在文章中,还有一个指向Java Maybe Type的Git存储库的链接,我觉得这很有趣,但我不认为单独使用它会降低检查代码膨胀。在互联网上做了一些研究之后,我想主要通过仔细设计可以减少空码膨胀。