Java中空指针异常该如何避免详解

网友投稿 371 2022-08-17


Java中空指针异常该如何避免详解

java中如何避免空指针异常,这也是由初级程序员成长到中级程序员的时候经常会遇到的问题。

程序员不知道或不信任正在使用的约定,并且小心的检查着null。还有当程序员写代码的时候,总是会依赖于通过返回空(NULL)来表明某些意义,因此需要调用者去检查Null。

有两种空指针的检查场景:

期望的结果就是null。期望的结果不是null。

第二种很简单,可以通过用assert或者允许程序报错,例如抛出NullPointerException。Assertions是一个从Java1.4加进来的高度未被利用的特性,语法是:

assert

或者

assert :

condition是一个布尔表达式,object是一个对象(其toString()方法的输出将会被包含在错误里)。

校对注:我测试了下,JDK1.4及其以上,运行前设置vm参数-ea

public static void main(String[] args) {String name = null;assert (name != null) : "name为空nullhttp://";}

Exception in thread "main"; java.lang.AssertionError: 变量name为空nullat LogUtil.main(LogUtil.java:37)

如果condition为false的话,assert将会抛出一个Error(AssertionError)。默认Java会忽略断言你可以通过在JVM中传入一个-ea参数来启用断言。

你可以为单独的一个包或者类启动关闭assertions。这意味着你可以在开发和测试的时候通过断言来验证代码,在发布产品的时候关闭它,尽管我下面展示的测试中并没有因为assertions而损失性能。在这个代码段中不用断言也可以,因为他会运行失败的,就像加了断言一样。唯一的区别是有了断言可能会发生的更快一些,更有意义,并且会附加一些额外的信息,而这可以帮助你弄明白失败的原因。

第一种有一点棘手。如果你对不能控制正在调用的这段代码,那你就卡住了。如果Null是一个合理的返回值,你就应该检查它。如果是你能够控制的代码,那就是个完全不同的故事情景了。尽量避免用NULL作为返回值。对于返回Collections的集合很容易,返回Empty(一个空集合或者数组),而不是一直用null作为返回值。对于不是返回Collections的方法会有一点复杂。考虑下面这个例子:

public interface Action {

void doSomething();}public interface Parser {

Action findAction(String userInput);}

Parser采用用户的输入作为参数,然后做一些事情(例如模拟一个命令行)。现在你可能会返回null,如果没找到对应输入的动作的话,这就导致了刚才说过的空指针检查。

一个可选的解决方案是永远不要返回null,而是返回一个空对象

public class MyParser implements Parser {

private static Action DO_NOTHING = new Action() {

public void doSomething() { /* do nothing */ }

};

public Action findAction(String userInput) {

// ...

if ( /* we can't find any actions */ ) {

return DO_NOTHING;

}

}}

比较这段代码:

Parser parser = ParserFactory.getParser();if (parser == null) {

// now what?

// this would be an example of where null isn't (or shouldn't be) a valid response}Action action = parser.findAction(someInput);if (action == null) {

// do nothing} else {

action.doSomething();}

和这段:

ParserFactory.getParser().findAction(someInput).doSomething();

这是个更好的设计,因为足够简洁,避免了多余的判断。

即便如此,或许比较合适的设计是:findAction()方法之恶杰抛出一个异常,其中包含一些有意义的错误信息—–特别是在这个案例中你依赖于用户的输入。

让findAction()方法抛出一个异常而不是简单的产生一个没有任何解释的NullPointerException 要好得多。

try {

ParserFactory.getParser().findAction(someInput).doSomething();} catch(ActionNotFoundException anfe) {

userConsole.err(anfe.getMessage());}

或者你认为try/catch 的机制太丑了,你的action应该跟用户提供一个反馈而不是什么都不做:

public Action findAction(final String userInput) {

/* Code http://to return requested Action if found */

return new Action() {

public void doSomething() {

userConsole.err("Action not found: " + userInput);

}

}}

补充:个人在做项目时,对NullPointerException的几点总结,请网友拍砖!!!多多提意见,

1.对于别人接口的返回对象要做非空判断,因为我们不清楚获得的对象会不会为空,对于Collection Map 我一般会调用CollectionUtils MapUtils ,对于返回的String对象,我会调StringUtils.isNotEmpty()进行非空判断。他们中isNotEmpty不仅判断了NULL 还判断了空集合和空串。例如从数据中查询的结果。工作流中返回的定价URL

2. 对于自己创建的对象,要留心对象进行哪些操作,中间会不会造成对象为空,如果可能加非空判断,尤其是对于集合的操作,很容易就报空指针!!!所以每次对操作集合时,我都会非常的留心。

3. 对于前台的领域对象要非常的留心,因为这些对象是框架创建的,假如我没有在前台的文本框内输入值,虽然提交时后台获得的是空串,但发生NullPointerException的概率很高。

4. 对于String 的操作尽量使用apache 的StringUtils类,与String相比这个是非常的安全。对于集合的操作使用apache的CollectionUtils 、MapUtils, 相比apache工具类的执行效率也非常的高,比如StringUtils.split();

有人说过多的判断会影响性能,我个人认为这里的性能牺牲和系统的安全相比是微不足道的。

总结


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Netty分布式pipeline管道创建方法跟踪解析
下一篇:Java 超详细讲解设计模式之一的原型设计模式
相关文章

 发表评论

暂时没有评论,来抢沙发吧~