文章目录
- 一、GroovyObject 接口简介
- 二、MetaClass 简介
- 三、使用 GroovyObject#invokeMethod 执行类方法
一、GroovyObject 接口简介
在类中 , 如果没有实现某个 方法 或者 成员属性 , 可以利用 元编程 替换类中的 方法或属性 ;
在编译字节码文件时 , 每个 Groovy 类都会被编译成 GroovyObject 接口对象 ;
代码语言:javascript复制/**
* 所有的 Groovy 类都要实现的接口
* <p>
* 在Java世界中使用Groovy对象尤其方便。
*/
public interface GroovyObject {
/**
* Invokes the given method.
*
* @param name 要执行的方法名
* @param args 方法调用方法参数
* @return 返回方法执行返回值
*/
@Internal // 标记为内部只是为了向后兼容, e.g. AbstractCallSite.createGroovyObjectGetPropertySite 会检查 `isMarkedInternal`
default Object invokeMethod(String name, Object args) {
return getMetaClass().invokeMethod(this, name, args);
}
/**
* 检索属性值。
*
* @param propertyName 属性名称
* @return 返回查到的属性值
*/
@Internal // 标记为内部只是为了向后兼容, e.g. AbstractCallSite.createGroovyObjectGetPropertySite will check `isMarkedInternal`
default Object getProperty(String propertyName) {
return getMetaClass().getProperty(this, propertyName);
}
/**
* 将给定属性设置为新值。
*
* @param propertyName 设置的属性名
* @param newValue 新属性
*/
@Internal // 标记为内部只是为了向后兼容, e.g. AbstractCallSite.createGroovyObjectGetPropertySite will check `isMarkedInternal`
default void setProperty(String propertyName, Object newValue) {
getMetaClass().setProperty(this, propertyName, newValue);
}
/**
* 返回给定类的元类。
*
* @return 此实例的元类
*/
MetaClass getMetaClass();
/**
* 允许用派生实现替换元类。
*
* @param metaClass 新的元类
*/
void setMetaClass(MetaClass metaClass);
}
二、MetaClass 简介
MetaClass 元类可以用于实现 元编程 的 方法注入 , 方法拦截 , 合成委托 等操作 ;
代码语言:javascript复制/**
* Groovy中的元类定义任何给定Groovy或Java类的行为。
* 元类接口定义了两个部分。
* 客户端 API,它是通过ExtendeMetaObjectProtocol接口
* 和Groovy运行时系统的契约定义的。
*
* 通常,编译器和Groovy运行时引擎与此类上的方法交互,
* 而元类客户端与MetaObjectProtocol接口定义的方法交互
*
* @see MetaClassImpl
* @see groovy.lang.MetaObjectProtocol
*/
public interface MetaClass extends MetaObjectProtocol {
}
三、使用 GroovyObject#invokeMethod 执行类方法
定义一个类 , 在其中定义 hello 方法 , 可以直接调用该方法 , 也可以通过 GroovyObject#invokeMethod 执行该方法 ;
代码示例 :
代码语言:javascript复制class Student {
def name;
def hello() {
println "Hello ${name}"
}
}
def student = new Student(name: "Tom")
// 直接调用 hello 方法
student.hello()
// 通过 GroovyObject#invokeMethod 调用 hello 方法
// 第二个参数是函数参数 , 如果为 void 则传入 null
student.invokeMethod("hello", null)
执行结果 :
代码语言:javascript复制Hello Tom
Hello Tom