Atitit避免出现空指针异常解决方案
1. Null的问题1
2. 强制区分一般引用vs 可空引用 vs 强制引用,或者说非空引用2
3. ?运算符(问号运算符) !感叹号运算符避免出现空指针异常,2
4. Java 8中的Optional类2
4.1.1. 为什么使用Optional要比常见的null检查强?3
5. 另一个救星! Objects.requireNonNull3
5.1.1. 为什么比if(myObj!=null)要好?3
6. 参考4
含空引用的编程语言是一个价值十亿美元的错误(译者注:图灵奖得主 Tony Hoare 说过)。但是为什么呢?当然,他们可能会导致NullReferenceException,但那又怎样?只要使用不当,一个语言的任何一个元素都可导致错误啊
换句话说,有两种情况会出现判空语句:
· null返回值按找约定是正常的返回值
· null返回值不是正常的返回值
第二种情况很简单。可以使用assert来判断或者是允许程序报错(即抛NullPointerException)。断言是一个被充分利用的Java特性,在1.4版本中加入了这个特性。语法如下:
NullPointerException最主要的问题是没有一个biz 说明。
带有说明的异常要比光秃秃的抛出一个NullPointerException要好的多。
作者:: 绰号:老哇的爪子 ( 全名::Attilax Akbar Al Rapanui 阿提拉克斯 阿克巴 阿尔 拉帕努伊 ) 汉字名:艾龙, EMAIL:[email protected]
转载请注明来源: http://blog.csdn.net/attilax
的根源在于C#无法表达出非空引用的概念,这也导致让编译器强制进行空检查变成一种过于繁重的任务。
为了应对这个问题,某条提议建议使用一种强制引用,以及一种明确的可空引用的定义。在提议中,可空引用将使用?后缀进行定义,正如可空值类型的定义方式一样。而强制引用,或者说非空引用将使用!后缀进行定义。
强制引用以及可空引用都应该被视为一种仅限于语言本身的概念,它们只是改变了编译器的行为,但不会改动所生成的IL代码
在编译器允许访问可空引用对象的任何方法或属性之前,必须明确地检查空引用。并且在将某个可空引用转型为强制引用之前,也必须对空引用进行检查。
强制引用需要编译器证实其中包含的值不可为空。由于这是一种仅限于编译器的规则,因此无法保证在反序列化等场景中能够同样生效。
在阅读这条提议的完整内容时,你会注意到其中提到的某个术语“一般引用”。它指的是C#中的普通引用,它既不是强制的,也不是明确定义为可空的。由于这种引用将被视为遗留代码,因此可以通过AllowGeneralReferences这一属性告诉编译器不允许在代码中使用一般引用。
在结合隐式变量定义时,可以在var关键字中使用!或?后缀。
简单的方法就是检查Optional包装器是否真的有值(使用isPresent方法)——你会怀疑这和使用if(myObj != null)相比有什么好处。别担心,这个我会解释清楚的
你可以使用orElse方法,这样万一封装的确实是一个null值的话可以用它来返回一个默认值——它的好处显而易见。在提取出真实值的时候可以避免调用ifPresent方法这样明显多余的方式了。
· 使用Optional最大的好处就是可以更明白地表述你的意图——返回null值的话会让消费者感到疑惑(当真的出现NPE的时候)这是不是故意返回的,因此还得查看javadoc来进一步定位。而使用Optional就相当明了了。
· 有了Optional你就可以彻底避免NPE了——如上所提,使用Optional.ofNullable,orElse以及orElseGet可以让我们远离NPE。
如果抛出NPE的话,我们怎么能确定到底是哪个是null的?
Objects.requireNonNull(key, "Key is null");
requireNonNull方法
· 如果对象不为null的话就返回它本身
· 如果值为null的话,返回的NPE会带有指定的消息
你所看到的栈跟踪信息会很清楚地看见Objects.requireNonNull的方法调用。这个再配合你自己的错误日志,可以让你更快地定位问题。。。至少在我看来是更快。
空指针的救星 - 博客 - 伯乐在线.htm
在Java中如何避免“!=null”式的判空语句? - ImportNew.htm
C#的未来:追踪空引用.htm