Groovy 理解元类(MetaClass)的概念

在 groovy 中,所有的对象都实现了 GroovyObject 接口,它就像我们提到过的其它类一样,声明在 groovy.lang 包中,GroovyObject 看起来有如下的格式:[code]public interface GroovyObject {

public Object invokeMethod(String name, Object args);

public Object getProperty(String property);

public void setProperty(String property, Object newValue);

public MetaClass getMetaClass();

public void setMetaClass(MetaClass metaClass);

}
[/code]在 groovy 中你的所有类都是通过 GroovyClassGenerator 来构建的,因此它们都实现了 GroovyObject这个接口并且有接口中的方法的默认实现——除了你自己选择实现它之外。

注意:如果你希望一个一般的 java 类也被作为一个 G roovy 类来组织,你必须实现GroovyObject 接口,为了便利性,你可以扩展抽象类 G roovyObjectSupport,这个类提供了默认的实现。

GroovyObject 与 MetaClass 协作,MetaClass 是 Groovy 元概念的核心,它提供了一个Groovy 类的所有的元数据,如可用的方法、属性列表,MetaClass 也实现了下列接口:[code]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)

[/code]这些方法进行真正的方法调用工作,使用 JAVA 反射 API(默认、并且性能更佳)或者通过透明创建一个反射类,GroovyOb ject 的 invokeMethod 方法默认实现总是转到相应的MetaClass。

MetaClass 被存储在一个名称为 Met aClassRegistry 的中心存储器中,同时 groovy 也从MetaClassReg istry 中获取 MetaClass。

图显示了一个概要图(当思考 groovy 处理方法调用的时候请想到这个图)

注意:MetaClassRegistry 类被设计为单例模式,不能被直接实现,但不管怎样,在代码中,可以使用 InvokerHelper 的一个工厂方法来引用到这个单例的注册中心。

通过图 7.2 的结构可以看到每个对象有一个 MetaClass,这种能力在默认的实现中没有使用,当前默认实现是在 MetaClassRegistry 中每一个类使用一个 MetaClass。当你需要定义的方法仅仅在一种类的实例上使用时这样是非常有用的(像 Ruby 的单态方法)。

注意:GroovyObject 引用到的 MetaClass 是 GroovyObject 在 MetaClassRegistry 中注册的 类型,他是不需要相同的,例如,一个特定的对象可以有一个特殊的 MetaClass(这个 MetaClass 可以与该对象类的其他对象的 MetaClass 不一样)。