Class當然是Groovy語言從Java語言繼承來的,這就是說Groovy語言也繼承了Java語言的反射機制。這意味著我們能夠像在Java語言裡使用反射那樣,在Groovy語言裡寫出諸如下面的代碼:
import java.lang.reflect.Method
class Testor {
def testDelegate()
{
'ok'
}
static void main(args) {
def t = new Testor()
Class cls = t.class
Method method = cls.getMethod('testDelegate',null)
println method.invoke(t,null)
}
}
當然,我們在Groovy語言裡很少會這樣用了,因為Groovy語言的MOP機制比起Java語言的反射機制來說,強大的很多倍。
總結來說,Groovy語言的MOP機制主要由以下幾種方法來實現:
第一, 就是Groovy Class本身的hook,包括重載"invokeMethod"和"set/getProperty"方法,和重載"methodMissing"和"propertyMissing"方法。這些方法都已經在不同的文字中反復被提及,在這裡就不再重述。
第二, 就是通過MetaClass來實現的MOP機制。
在Groovy語言中,所有的類都起源於GroovyObject接口,該接口中有如下的兩個方法:
public MetaClass getMetaClass();
public void setMetaClass(MetaClass metaClass);
我們的所有對象的MetaClass對象,都是通過這兩個方法而來的。
在MetaClass對象中,我們可以實現如下的一些方法:
Object invokeMethod(Object obj, String methodName, Object args)
Object invokeMethod(Object obj, String methodName, Object[] args)
Object invokeStaticMethod(Object obj, String methodName, Object[] args)
Object invokeConstructor(Object[] args)
分別用來調用方法、靜態方法和屬性。同時,我們還有一些用來自省的屬性和方法,如:"properties"、"respondsTo"和"hasProperty"等等。
所以,我們要想使用MetaClass來實現MOP機制,就需要實現一個我們自己的MetaClass,然後把它通過"setMetaClass"方法set到GroovyObject對象中,從而達到使用MetaClass的目的。
很顯然,要通過這種方法來實現Groovy語言的MOP機制不是很靈活,遠不如上面的hook好用。
第三, 就是通過ExpandoMetaClass來實現的MOP機制
據說,ExpandoMetaClass類的使用,起源於Grails項目,由於它實現MOP機制的極大方便性,從Groovy1.1開始,就被引入到了Groovy語言的核心API。
與上面的MetaClass類不同的是,MetaClass類是通過Groovy的對象的"setMetaClass"和"getMetaClass"引入;而ExpandoMetaClass類是由"java.lang.Class"類的"metaClass"引入。
如下面的例子:
class Testor5 {
private delegate
def testDelegate()
{
'ok'
}
static void main(args) {
def t = new Testor5()
t.testDelegate()
Testor5.metaClass.test = {
->
'invoke test function'
}
def t1 = new Testor5()
println t1.test()
}
}
當然,ExpandoMetaClass類也可以對單獨的對象進行添加方法和屬性,體現了極大的靈活性和動態性。
所有這些,都將會在以後的篇幅中詳細描述,在這裡就不再細說。