Groovy神奇的NullObject

在這篇文章裏,我將向你展現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 norGroovy’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本身了,我以爲這就是不一致。

相關文章
相關標籤/搜索