在这篇文章中,我将解释Java中null和Groovy中null的一些明显差异。
让我们从以下几行开始:
Object o = null
该语句在Java和Groovy中工作正常(除了Java在行尾需要分号)。
但是,其效果略有不同。
在Java中,null是一种特殊的文字,它被分配给不指向任何对象的引用类型。 每次您尝试对空引用执行任何操作(例如调用方法或访问成员变量)时,都会引发NullPointerException。
在Groovy中,null是一个对象! 它是org.codehaus.groovy.runtime.NullObject的实例。 大多数情况下,如果您尝试访问方法或成员变量,则NullObject会引发NullPointerException。 但是,可以在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对象可以保护开发人员免受NullPointerExceptions的侵害。 asBoolean()始终返回false,并确保在必要时可以将null转换为布尔值。 iterator()返回java.util.Collections $ EmptyIterator的实例。 因此,可以安全地遍历对象而无需显式检查null。
有趣的是,在正式的常规文档中我还没有找到有关NullObject的任何信息。 Groovy的Null Object Pattern中没有提到与Java的区别 。
可能没有实际的用例,但是您甚至可以创建自己的NullObject实例:
Class c = null.getClass()
NullObject myNull = c.newInstance()
但是请注意,如果传入默认的NullObject实例,则equals()方法仅返回true。 因此对于您自己的NullObject实例,它可能无法正常工作:
assert false == myNull.equals(myNull)
assert true == myNull.equals(null)
您还可以修改NullObject的metaClass以添加您自己的方法:
NullObject.metaClass.myMethod = { println "I am null" }
null.myMethod()
翻译自: https://www.javacodegeeks.com/2013/11/groovys-magical-nullobject.html