我使用x!=null以避免NullPointerException。还有其他选择吗?
if (x != null) {
// ...
}
我使用x!=null以避免NullPointerException。还有其他选择吗?
if (x != null) {
// ...
}
当前回答
如果您认为对象不应为空(或是错误),请使用断言。如果您的方法不接受null参数,请在javadoc中说它并使用断言。
您必须检查对象!=仅当您想处理对象可能为空的情况时才为空。。。
有人建议在Java7中添加新注释,以帮助处理null/notnull参数:http://tech.puredanger.com/java7/#jsr308
其他回答
public static <T> T ifNull(T toCheck, T ifNull) {
if (toCheck == null) {
return ifNull;
}
return toCheck;
}
好的,我现在已经从技术上回答了一百万次,但我不得不这么说,因为这是一场与Java程序员的无休止的讨论。
很抱歉,我不同意以上所有内容。我们必须在Java中测试null的原因是,Java程序员一定不知道如何处理内存。
我这么说是因为我有很长的C++编程经验,而我们不这么做。换句话说,你不需要这样做。注意,在Java中,如果你命中了一个悬空指针,你会得到一个正常的异常;在C++中,此异常通常不会被捕获并终止程序。
不想这样做吗?然后遵循C/C++中的一些简单规则。
不要轻易实例化事物,认为每一个“新”都会给你带来很多麻烦,并遵循这些简单的规则。
一个类只能通过3种方式访问内存->
它可以“拥有”类成员,他们将遵循以下规则:所有“HAS”成员都是在构造函数中“新建”的。您将在析构函数或等效的close()中关闭/取消分配同一类的Java函数,而不是其他类。
这意味着您需要记住(就像Java一样)谁是每个资源的所有者或父级,并尊重该所有权。对象只能由创建它的类删除。此外->
一些成员将被“使用”,但不拥有或“拥有”。这是另一个类中的“OWN”,并作为参数传递给构造函数。由于这些是由另一个类拥有的,我们永远不会删除或关闭它,只有父类才能删除或关闭。类中的方法还可以实例化本地对象供内部使用,这些对象永远不会传递到类的外部,或者它们应该是正常的“有”对象。
最后,要使所有这些工作正常进行,您需要有一个严格的设计,以层次结构形式使用类,并且不进行循环。
在这种设计下,遵循上述规则,层次结构设计中的子类不可能访问被破坏的指针,因为这意味着父类在子类之前被破坏,而层次结构非循环设计不允许这样做。
最后,还要记住,在启动系统时,应该从上到下构建层次结构,并从下到上销毁。任何地方都不会有空指针,或者有人违反了规则。
有时,您可以使用对其参数进行操作的方法来定义对称操作:
a.f(b); <-> b.f(a);
如果你知道b永远不可能为空,你可以交换它。它对equals最有用:而不是foo.equals(“bar”);最好使用“bar”。equals(foo);。
我喜欢Nat Pryce的文章。以下是链接:
用多态调度避免空值避免使用“告诉,不要问”风格的null
在文章中,还有一个指向Java Maybe Type的Git存储库的链接,我觉得这很有趣,但我不认为单独使用它会降低检查代码膨胀。在互联网上做了一些研究之后,我想主要通过仔细设计可以减少空码膨胀。
Java中常见的“问题”确实存在。
首先,我的想法是:
我认为,当传递NULL时,如果NULL不是有效值,“吃掉”某些东西是不好的。如果您退出方法时没有出现某种错误,那么这意味着您的方法中没有任何错误,这是不正确的。在这种情况下,您可能会返回null,在接收方法中,您再次检查null,并且它永远不会结束,结果是“if!=null”等。。
因此,IMHO,null必须是阻止进一步执行的关键错误(即,null不是有效值)。
我解决这个问题的方法是:
首先,我遵循以下惯例:
所有公共方法/API始终检查其参数是否为空所有私有方法都不检查null,因为它们是受控制的方法(如果上面没有处理null指针异常,就让它终止)唯一不检查null的其他方法是实用程序方法。他们是公开的,但如果你出于某种原因打电话给他们,你知道你通过了哪些参数。这就像试图在水壶里烧水而不提供水。。。
最后,在代码中,public方法的第一行如下所示:
ValidationUtils.getNullValidator().addParam(plans, "plans").addParam(persons, "persons").validate();
注意,addParam()返回self,这样您就可以添加更多的参数来检查。
如果任何参数为空,方法validate()将抛出checked ValidationException(checked或unchecked更多是设计/品味问题,但我的ValidationException已选中)。
void validate() throws ValidationException;
例如,如果“计划”为空,则消息将包含以下文本:
“参数[plans]遇到非法参数值null”
正如您所看到的,用户消息需要addParam()方法中的第二个值(字符串),因为即使有反射(无论如何都不是本文的主题…),也无法轻松检测传入的变量名。
是的,我们知道,在这一行之外,我们将不再遇到空值,因此我们只需安全地调用这些对象上的方法。
这样,代码就干净、易于维护和可读。