我使用x!=null以避免NullPointerException。还有其他选择吗?
if (x != null) {
// ...
}
我使用x!=null以避免NullPointerException。还有其他选择吗?
if (x != null) {
// ...
}
当前回答
我发现在这种情况下,Guava前提条件非常有用。我不喜欢将空值留给空指针异常,因为理解NPE的唯一方法是定位行号。生产版本和开发版本中的行号可能不同。
使用Guava Preconditions,我可以检查空参数并在一行中定义有意义的异常消息。
例如
Preconditions.checkNotNull(paramVal, "Method foo received null paramVal");
其他回答
通过遵循问题的大多数其他答案,您可以避免很多事情,以避免NullPointerException。我只想添加Java9中引入的其他一些方法,以优雅地处理这种情况,并展示一些旧的方法也可以使用,从而减少您的工作量。
公共静态布尔值isNull(对象obj)如果提供的引用为null,则返回true,否则返回错误。自Java 1.8以来公共静态布尔值nonNull(对象obj)如果提供的引用为非null,则返回true,否则返回错误。自Java 1.8以来公共静态<T>T requireOnNullElse(T对象,T默认对象)如果第一个参数为非null,则返回第一个参数,否则返回非空的第二个参数。自Java 9以来公共静态<T>T requireOnNullElseGet(T obj,供应商<?扩展T>供应商)如果第一个参数为非空,则返回第一个参数,否则返回supplier.get()的非空值。自Java 9以来公共静态<T>T requireOnNull(T obj,供应商<字符串>消息供应商)检查指定的对象引用是否为空,否则将引发自定义的NullPointerException。自Java 1.8以来
有关上述功能的更多详细信息,请参阅此处。
对于实用程序类,可以检查参数是否为空。
在所有其他情况下,您可能不必这样做。尽可能使用封装,从而减少您想检查null的地方。
Guava是Google提供的一个非常有用的核心库,它有一个很好且有用的API来避免空值。我发现UsingAndAvoidingNullExplain非常有用。
正如wiki中所解释的:
可选<T>是用非空值。可选可以包含非空T引用(在这种情况下,我们称引用为“present”),或者它可能包含什么都没有(在这种情况下,我们说引用“不存在”)。从来没有称为“包含null”
用法:
Optional<Integer> possible = Optional.of(5);
possible.isPresent(); // returns true
possible.get(); // returns 5
您可以为对象和字符串创建一个通用方法,以便在应用程序中完全使用它-这可以帮助您和您的同事:创建一个类,例如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
}
如果不允许未定义的值:
您可以配置IDE以警告您可能的空取消引用。例如,在Eclipse中,请参阅首选项>Java>编译器>错误/警告/空分析。
如果允许未定义的值:
如果您想定义一个新的API,其中未定义的值是有意义的,请使用OptionPattern(可能在函数语言中很熟悉)。它具有以下优点:
API中明确说明是否存在输入或输出。编译器强制您处理“未定义”的情况。选项是monad,因此不需要进行冗长的空检查,只需使用map/foreach/getOrElse或类似的组合符即可安全地使用该值(示例)。
Java 8内置了可选类(推荐);对于早期版本,有一些库选项,例如Guava的Optional或FunctionalJava的Option。但是,像许多函数样式模式一样,在Java中使用Option(甚至是8)会产生一些样板,您可以使用不那么冗长的JVM语言(例如Scala或Xtend)来减少这些样板。
如果必须处理可能返回null的API,那么在Java中就做不了什么了。Xtend和Groovy有Elvis运算符?:和空安全解引用运算符?。,但请注意,如果引用为null,则返回null,因此它只是“延迟”了对null的正确处理。