程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Groovy >> Groovy探索之MOP 三 Class、MetaClass和ExpandoMetaClass

Groovy探索之MOP 三 Class、MetaClass和ExpandoMetaClass

編輯:Groovy

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類也可以對單獨的對象進行添加方法和屬性,體現了極大的靈活性和動態性。

所有這些,都將會在以後的篇幅中詳細描述,在這裡就不再細說。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved