[英]Java Null Reference Best Practice
在java中,以下哪一种处理可能为空的引用的方式更为“可接受”? 请注意,空引用并不总是表示错误...
if (reference == null) {
//create new reference or whatever
}
else {
//do stuff here
}
要么
try {
//do stuff here
}
catch (NullPointerException e) {
//create new reference or whatever
}
已经给出的答案非常好(不要使用控制流的例外;抛出和处理的例外是昂贵的)。 还有另一个重要的原因,特别是没有捕获NullPointerException
。
考虑执行以下操作的代码块:
try {
reference.someMethod();
// Some other code
}
catch (NullPointerException e) {
// 'reference' was null, right? Not so fast...
}
这似乎是一种处理reference
无效的安全方法......但是如果引用是非null而someMethod()
引发了NPE呢? 或者如果在try
块中的其他位置引发了NPE会怎么样? 捕获NPE是防止错误被发现和修复的可靠方法。
捕获异常相对昂贵。 通常最好是检测条件而不是对它做出反应。
当然是这一个
if (reference == null) {
//create new reference or whatever
}
else {
//do stuff here
}
我们不应该依赖于例外的决策,而这些例外根本不是为了这个目的而给出的,它们也很昂贵。
那么如果您没有做出决定并且只是验证初始化变量那么
if (reference == null) {
//create new reference or whatever
}
//use this variable now safely
我看到一些自动代码生成器在accessors / getter方法中包装了这个东西。
我认为一般情况下应该为特殊情况保留一个例外 - 如果有时需要空引用,则应检查它并明确处理它。
从答案中可以清楚地看出,抓住异常并不好。 :)例外肯定不是免费的。 这可能有助于您深入理解它。 。
我还想在将您的对象与已知值进行比较时提及另一种做法。
这是完成这项工作的传统方法:(检查对象是否为null然后进行比较)
Object obj = ??? //We dont know whether its null or not.
if(obj!=null && obj.equals(Constants.SOME_CONSTANT)){
//your logic
}
但是这样,你不必为你的对象烦恼:
Object obj = ???
if(Constants.SOME_CONSTANT.equals(obj)){ //this will never throw
//nullpointer as constant can not be null.
}
第一个是抛出异常是一项代价高昂的操作。
第一种形式:
if (reference == null)
{
//create new reference or whatever
}
else
{
//do stuff here
}
您不应该使用控制流的异常。
例外情况是处理在正常操作条件下通常不会发生的特殊情况。
您应该使用异常捕获,而不希望出现错误。 如果某些东西可以为null,那么你应该检查一下。
也许在我们可以开始做的时候,try catch方法会在这种情况下开始变得有意义
try {
//do stuff here
}
catch (NullPointerException e) {
//create new reference or whatever
retry;
}
如果您使用必须使用的“安全”样式开发代码,这与您的开发风格有关
if(null == myInstance){
// some code
}else{
// some code
}
但是如果你不使用这种风格至少应该捕获异常,但在这种情况下它是NullPointerException,我认为最好将输入参数检查为null而不是等待抛出异常。
既然你要求最佳实践,我想指出Martin Fowler建议引入一个空引用的子类作为最佳实践。
public class NullCustomer extends Customer {}
因此,您可以避免处理未经检查的NullPointerException的麻烦。 可能返回Customer值为null的方法将返回NullCustomer而不是null。
你的支票看起来像:
final Customer c = findCustomerById( id );
if ( c instanceof NullCustomer ) {
// customer not found, do something ...
} else {
// normal customer treatment
printCustomer( c );
}
在我看来,在某些情况下允许捕获NullPointerException以避免对空引用的复杂检查并增强代码可读性,例如
private void printCustomer( final Customer c ) {
try {
System.out.println( "Customer " + c.getSurname() + " " + c.getName() + "living in " + c.getAddress().getCity() + ", " + c.getAddress().getStreet() );
} catch ( NullPointerException ex ) {
System.err.println( "Unable to print out customer information.", ex );
}
反对它的一个论点是,通过检查单个成员为空,您可以编写更详细的错误消息,但这通常是没有必要的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.