在这篇文章里,我将向你展现Java和Groovy中null
不怎么明显的的区别。java
让咱们从下面这行代码开始:安全
Object o = null
这条语句在Java和Groovy下均可以运行(只是在Java下须要在行尾加一个;
)。指针
然而,它们是有略微的区别的。code
在Java中,null
是一个特殊的字面值。它被分配一个引用类型,但没有指向任何对象。每次都你试图在一个null
引用上作些什么的时候(像调用方法或访问变量),都会抛一个NullPointerException
。对象
在Groovy中,null
是一个对象。它是org.codehaus.groovy.runtime.NullObject
的一个实例。大多数时候,NullObject会抛NullPointerException,若是你试图在null上调用一个方法或者变量。然而,NullObject的一些方法是能够调用的:文档
import org.codehaus.groovy.runtime.NullObject assert NullObject == null.getClass() assert true == null.equals(null) assert false == null.asBoolean() assert "null!" == null + "!" assert false == null.iterator().hasNext()
能够看出,null
对象能够预防空指针异常。asBoolean()返回老是返回false,这样就能够保证null能够在须要的时候被转换成一个boolean值。iterator()方法返回的是一个java.util.Collections$EmptyIterator,由于这样就能够安全的在任何对象上调用iterator方法,而不须要显示的检查null。get
有趣的是,我在groovy的官方文档没有找到任何NullObject的信息。在Differences from Java nor和Groovy’s Null Object Pattern,也没有提到。it
很难找到实用案例来讲明NullObject,不过,你能够建立你本身的NullObject实例。io
Class c = null.getClass() NullObject myNull = c.newInstance()
请注意下面,只有equals()方法只有在你传NullObject的默认实例时才返回true。因此,你的NullObject实例只会返回false。import
assert false == myNull.equals(myNull) assert true == myNull.equals(null)
你也能够经过修改NullObject的元信息以添加你本身的方法:
NullObject.metaClass.myMethod = { println "I am null" } null.myMethod()
PS:事实上,从false == myNull.equals(myNull)
看到,这个语言一样没有很高度的一致性
。由于连本身都不equals本身了,我以为这就是不一致。