在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
}
答案 0 :(得分:14)
已经给出的答案非常好(不要使用控制流的例外;抛出和处理的例外是昂贵的)。另外还有一个重要的原因,特别是没有抓住NullPointerException
。
考虑执行以下操作的代码块:
try {
reference.someMethod();
// Some other code
}
catch (NullPointerException e) {
// 'reference' was null, right? Not so fast...
}
这似乎是一种处理reference
无效的安全方法......但如果引用为非null且someMethod()
提升了NPE,该怎么办?或者,如果在try
区块的其他位置引发了NPE,该怎么办?捕获NPE是防止错误被发现和修复的必然方法。
答案 1 :(得分:11)
捕获异常相对昂贵。通常最好是检测条件而不是对它做出反应。
答案 2 :(得分:7)
当然是这个
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方法中包装了这个东西。
答案 3 :(得分:2)
我认为一般情况下应该为异常情况保留一个例外 - 如果有时需要空引用,则应检查并明确处理它。
答案 4 :(得分:2)
从答案中可以清楚地看出,抓住异常并不好。 :) 例外肯定不是免费的。 This might help you to understand it in depth.。
我还想在将您的对象与已知值进行比较时提及另一种做法
这是完成这项工作的传统方式:(检查对象是否为空,然后进行比较)
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.
}
答案 5 :(得分:1)
第一个,抛出异常是一项代价高昂的操作。
答案 6 :(得分:1)
第一种形式:
if (reference == null)
{
//create new reference or whatever
}
else
{
//do stuff here
}
您不应该使用控制流的例外。
例外情况是处理在正常操作条件下通常不会发生的特殊情况。
答案 7 :(得分:0)
您应该使用异常捕获,而不希望出现错误。如果可以为空,那么你应该检查一下。
答案 8 :(得分:0)
当我们开始做
时,尝试捕捉方法可能会在这种情况下开始变得有意义try {
//do stuff here
}
catch (NullPointerException e) {
//create new reference or whatever
retry;
}
答案 9 :(得分:0)
这与您的开发风格有关,如果您使用“安全”风格开发代码,则必须使用
if(null == myInstance){
// some code
}else{
// some code
}
但是如果你不使用这种风格至少你应该捕获异常,但在这种情况下它是NullPointerException,我认为最好将输入参数检查为null而不是等待抛出异常。
答案 10 :(得分:0)
由于您要求最佳实践,我想指出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 );
}
反对它的论点是,通过检查单个成员为空,您可以编写更详细的错误消息,但这通常是没有必要的。