Java:如何有效检查空指针
有一些模式可用于检查方法的参数是否已null
赋值。
首先,经典的。在自制代码中很常见,并且很容易理解。
public void method1(String arg) { if (arg == null) {
throw new NullPointerException("arg");
}
}
其次,您可以使用现有框架。该代码看起来更好一些,因为它仅占用一行。缺点是它可能调用另一个方法,这 可能 会使代码的运行速度慢一些,具体取决于编译器。
public void method2(String arg) { Assert.notNull(arg, "arg");
}
第三,您可以尝试调用对对象没有副作用的方法。乍一看可能很奇怪,但它的令牌少于上述版本。
public void method3(String arg) { arg.getClass();
}
我还没有看到广泛使用的第三种模式,感觉就像我自己发明了这种模式。我喜欢它的简短性,因为编译器有很大的机会完全优化它或将其转换为一条机器指令。我还用行号信息编译我的代码,因此,如果NullPointerException
抛出a,我可以将其追溯到确切的变量,因为每行只有一个这样的检查。
您喜欢哪种支票,为什么?
回答:
arg.getClass();
很聪明,但是除非这个习惯用法得到广泛采用,否则我宁愿使用更清晰,更详细的方法,而不是保存一些字符。我是“一次编写,多次阅读”的程序员。
其他方法是自记录文档:您可以使用一条日志消息来澄清发生了什么-在读取代码以及运行时都使用此日志消息。
arg.getClass()
就目前而言,它不是自我记录。您至少可以使用注释或向代码审阅者澄清一下:
arg.getClass(); // null check
但是您仍然没有机会像使用其他方法一样在运行时中放置特定消息。
我尝试遵循以下准则:
http://data.opengeo.org/GEOT-290810-1755-708.pdf
assert param > 0;
if (param == null) throw new IllegalArgumentException("param cannot be
null");
if (getChild() == null) throw new NullPointerException("node must have
children");
,由于这可能是有关如何null
最有效地捕获潜在问题的问题,因此我不得不提及我的首选处理方法null
是使用静态分析,例如,类型注释(例如,@NonNull
la
。我最喜欢的检查它们的工具是:
Checker框架:
Java的自定义可插入类型
https://checkerframework.org/manual/#checker-
guarantees
如果它是我的项目(例如,不是带有公共API的库),并且可以在整个过程中使用Checker Framework,则:
我可以在API中更清楚地记录我的意图(例如,此参数可能不为null(默认值),但此参数可能为null(
@Nullable
;方法可能返回null;等等)。此注释恰好在声明中,而不是在Javadoc中更远的地方,因此更有可能得到维护。静态分析将提前标记潜在的逻辑缺陷(例如,我试图将可能为null的变量传递给仅接受非null参数的方法),而不是取决于运行时发生的问题。
另外一个好处是,该工具允许我将注释放入注释中(例如`/ @Nullable
/),因此我的库代码可以与带类型注释的项目和非带类型注释的项目兼容(不是我可以使用任何这些项目)。
,这是《 GeoTools开发人员指南》中的部分:
http://data.opengeo.org/GEOT-290810-1755-708.pdf
Java语言已经有两年了,现在可以使用assert关键字。此关键字可用于执行仅调试检查。尽管此功能有多种用途,但一种常见的用途是检查私有(而非公共)方法的方法参数。其他用途是后置条件和不变式。
断言编程
前提条件(例如私有方法中的参数检查)通常是断言的简单目标。后置条件和不变式有时不那么直率,但更有价值,因为非平凡条件有更多被破坏的风险。
- 在参考模块中进行地图投影之后,一个断言执行逆地图投影,并使用原始点(后置条件)检查结果。
- 在DirectPosition.equals(Object)实现中,如果结果为true,则该断言确保hashCode()与Object协定所要求的相同。
private double scale( int scaleDenominator ){ assert scaleDenominator > 0;
return 1 / (double) scaleDenominator;
}
您可以使用以下命令行参数启用断言:
java -ea MyApp
您只能使用以下命令行参数打开GeoTools断言:
java -ea:org.geotools MyApp
您可以禁用特定程序包的断言,如下所示:
java -ea:org.geotools -da:org.geotools.referencing MyApp
严格禁止在公共方法上使用断言;因为所报告的错误是在客户端代码中造成的-
坦白地说,当他们搞砸了时,先用IllegalArgumentException告诉他们。
public double toScale( int scaleDenominator ){ if( scaleDenominator > 0 ){
throw new IllegalArgumentException( "scaleDenominator must be greater than 0");
}
return 1 / (double) scaleDenominator;
}
如果可能,请执行自己的null检查;抛出IllegalArgumentException或NullPointerException,并提供有关发生问题的详细信息。
public double toScale( Integer scaleDenominator ){ if( scaleDenominator == null ){
throw new NullPointerException( "scaleDenominator must be provided");
}
if( scaleDenominator > 0 ){
throw new IllegalArgumentException( "scaleDenominator must be greater than 0");
}
return 1 / (double) scaleDenominator;
}
以上是 Java:如何有效检查空指针 的全部内容, 来源链接: utcz.com/qa/431841.html