我使用x!=null以避免NullPointerException。还有其他选择吗?
if (x != null) {
// ...
}
我使用x!=null以避免NullPointerException。还有其他选择吗?
if (x != null) {
// ...
}
当前回答
如果您使用的是java8或更高版本,请从java.util.Objects获取isNull(yourObject)。
示例:-
String myObject = null;
Objects.isNull(myObject); //will return true
用法:以下代码返回非空值(如果名称不为空,则返回该值,否则返回默认值)。
final String name = "Jobin";
String nonNullValue = Optional.ofNullable(name).orElse("DefaultName");
其他回答
无论您在何处传递数组或向量,请将它们初始化为空值,而不是空值。-这样可以避免大量检查null,一切都很好:)
public class NonNullThing {
Vector vectorField = new Vector();
int[] arrayField = new int[0];
public NonNullThing() {
// etc
}
}
好的,我现在已经从技术上回答了一百万次,但我不得不这么说,因为这是一场与Java程序员的无休止的讨论。
很抱歉,我不同意以上所有内容。我们必须在Java中测试null的原因是,Java程序员一定不知道如何处理内存。
我这么说是因为我有很长的C++编程经验,而我们不这么做。换句话说,你不需要这样做。注意,在Java中,如果你命中了一个悬空指针,你会得到一个正常的异常;在C++中,此异常通常不会被捕获并终止程序。
不想这样做吗?然后遵循C/C++中的一些简单规则。
不要轻易实例化事物,认为每一个“新”都会给你带来很多麻烦,并遵循这些简单的规则。
一个类只能通过3种方式访问内存->
它可以“拥有”类成员,他们将遵循以下规则:所有“HAS”成员都是在构造函数中“新建”的。您将在析构函数或等效的close()中关闭/取消分配同一类的Java函数,而不是其他类。
这意味着您需要记住(就像Java一样)谁是每个资源的所有者或父级,并尊重该所有权。对象只能由创建它的类删除。此外->
一些成员将被“使用”,但不拥有或“拥有”。这是另一个类中的“OWN”,并作为参数传递给构造函数。由于这些是由另一个类拥有的,我们永远不会删除或关闭它,只有父类才能删除或关闭。类中的方法还可以实例化本地对象供内部使用,这些对象永远不会传递到类的外部,或者它们应该是正常的“有”对象。
最后,要使所有这些工作正常进行,您需要有一个严格的设计,以层次结构形式使用类,并且不进行循环。
在这种设计下,遵循上述规则,层次结构设计中的子类不可能访问被破坏的指针,因为这意味着父类在子类之前被破坏,而层次结构非循环设计不允许这样做。
最后,还要记住,在启动系统时,应该从上到下构建层次结构,并从下到上销毁。任何地方都不会有空指针,或者有人违反了规则。
如果不允许未定义的值:
您可以配置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的正确处理。
问这个问题表明你可能对错误处理策略感兴趣。如何以及在哪里处理错误是一个普遍存在的体系结构问题。有几种方法可以做到这一点。
我最喜欢的是:允许异常在“主循环”或其他具有适当职责的函数中波动-捕获它们。检查错误情况并适当处理它们可以被视为一项专门的责任。
当然,也要看看面向方面编程——它们有很好的方法将if(o==null)handleNull()插入到字节码中。
如果不允许空值
如果从外部调用方法,请从以下内容开始:
public void method(Object object) {
if (object == null) {
throw new IllegalArgumentException("...");
}
然后,在该方法的其余部分中,您将知道该对象不为空。
如果它是一个内部方法(不是API的一部分),只需记录它不能为空,就可以了。
例子:
public String getFirst3Chars(String text) {
return text.subString(0, 3);
}
但是,如果您的方法只是传递值,而下一个方法传递值等,则可能会出现问题。在这种情况下,您可能需要检查上述参数。
如果允许为空
这真的取决于。如果发现我经常这样做:
if (object == null) {
// something
} else {
// something else
}
所以我分支,做两件完全不同的事情。没有难看的代码片段,因为我确实需要根据数据做两件不同的事情。例如,我应该处理输入,还是应该计算一个好的默认值?
实际上,我很少使用“if(object!=null&&…”这个成语。
如果你展示了你通常使用这个习语的例子,那么给你举例可能会更容易。