在调用某个方式,接收返回值时,要先判断返回值是否为null,然后才能继续使用返回值的某个方法,这种情况下,你是否非常希望像写jQuery代码一样的书写java代码?而且不用担心空指针问题么?在个人做过与接触过的系统中,个人感觉一半左右的bug问题,都是由于各种**"空指针"**引起的,如何有效的避免这类问题,提高代码质量,结合网上查询的内容与思考,整理如下.
##值类型与引用类型##
在java世界上,存在两种数据类型:
基本类型(4类8种):
1.1 布尔型:boolean(默认值false)
1.2 字符型:char(默认值0)
1.3 整数型:byte,short,int,long(默认值为0)
1.4 浮点数型:float,double(默认值为0.0)
引用类型:所有非基本类型的都为引用类型,所有引用类型的默认值为null.
##什么是null##
在java中,null是一个关键词,代表不确定的对象,可以将null赋值给引用类型,但是不可以赋值给基本数据类型,比如:
<pre> <code> int a = null;//错误的 Object obj = null;//正确 Integer b = null;//正确,因为Integer是int的包装类,是引用类型,不是基本类型 </code> </pre>
将1个对象赋值为null,主要有两个目的:
实现对象的延迟初始化:
在这种情况下,主要是由于创建1个对象需要很大的开销,只在需要调用该对象时才初始化,但是这种模式也是慎用,参见<<Effective Java>>的第71条.
释放内存,等待垃圾回收器回收该对象
当引用对象为null时,垃圾回收器运行时,将会销毁该对象.
##null与Object对象##
null不是对象,也不是Object的实例,验证代码如下:
<pre> <code> public class Main{ public static void main(String[] args){ if(null instanceof java.lang.Object){ System.out.println("null是java.lang.Object的类型");//不会输出 }else{ System.out.println("null不是java.lang.Object的类型");//会输出该结果 } } } </code> </pre>
##object==null与null==object的区别##
在判断1个对象是否为null时,可以有这两种写法,这两种写法一样么?
看下边的代码:
<pre> <code> Object obj = null; if(obj==null){ System.out.println("test obj==null"); } if(null==obj){ System.out.println("test null==obj"); } </code> </pre>
就测试结果来说,两种写法是一样的.
但是很多人会选择采用第2种写法,网上有说法是为了防止出现object=null这种的赋值错误.
个人见识到此为止,推荐第2种写法.
##String与null##
先看一段代码:
<pre> <code> @Test public void testStringWithNull(){ String s1 = null,s2=null,s3="test"; System.out.println(s1+s2+s3); } </code> </pre>
运行后,可以看到输出结果前边多了两个null.显然,在做String处理时,一定要考虑到null的情况.
##容器(集合)类与null##
有一些容器(集合)支持null的存储,如
- List可以存放多个null元素
- Map的key和value都可以存放null 所以在使用这些容器(集合)时,一定要注意存放元素为null的判断.
##API接口返回值的处理原则(返回空对象,返回null,还是抛异常?)##
API接口的返回值遵循以下原则:
返回值不要返回Null,可以返回空的对象或空的集合
如果方法校验不通过,无法返回结果对象,可以抛出异常,而不是返回null,并在方法签名中注明抛出异常的原因等
##Null Object Pattern##
Null Object模式详细说明可以参考wiki.
我觉得这里http://segmentfault.com/q/1010000000114775说的挺好.
有一个NullObject与原有业务对象实现相同的接口(或继承同一个父类),让客户端调用时可以无感知(也不必判定null)
摘一张图来说明一下:
其中,RealObject是期望得到的结果,但是如果执行过程中出现错误等,将返回NullObejct对象,而不是null,从而规避"空指针"异常等问题
采用这种方式,可以非常好的实现链式编程,像jQuery一样的代码书写形式.
这种模式的实现可以参考json解析框架:Jackson.
使用Optional类,我们可以对文章开头的代码处理如下:
##Java8 optional##
Java8为了解决空指针对应的一些问题,引入了一个新的Optional类,Optional类的javadoc描述为:
这是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
具体的用法可以参考java8 optional深度解析
##思考##
代码优化之路,代码应该怎么写?
扩展阅读:
参考文档:
转载于:https://my.oschina.net/itwarcraft/blog/343175