给定一个类名,我想动态创建一个Groovy类,向其添加属性和方法。我使用创建新类
instance = this.class.classLoader.parseClass(
"public class $name {}")
对于我使用的方法
instance.metaClass."$it.key" = it.value
其中it.key是字符串(方法名),it.value是闭包。这很方便,因为我可以指定方法参数类型并进行类型检查。但是,如果不给它赋值,就无法指定动态创建的属性类型。我可以通过显式定义属性的getter和setter来解决此问题。这可行,但是metaClass.name
= value或metaClass.getName =
{}似乎都没有在类中实际创建字段,因为Java字段运算符不适用于创建的属性。是否可以在Groovy类中添加属性并指定其类型,而无需为其分配初始值或显式定义getter和setter方法?有没有一种方法可以向Groovy类添加新字段?这是脚本:
class SomeClass {
Integer p1
String p2
}
class ClassBuilder {
def name
def instance
def properties
def methods
def ClassBuilder() {
properties = [:]
methods = [:]
}
def set_name(name) {
this.name = name
}
def add_property(name, type) {
properties[name] = type
}
def add_method(name, closure) {
methods[name] = closure
}
def get_instance() {
instance = this.class.classLoader.parseClass(
"public class $name {}")
properties.each {
instance.metaClass."$it.key" = null
//doesn't work
instance.metaClass."$it.key".type = it.value
}
methods.each {
instance.metaClass."$it.key" = it.value
}
return instance
}
}
builder = new ClassBuilder()
builder.set_name('MyClass')
builder.add_property('property1', String)
builder.add_property('property2', SomeClass)
builder.add_method('method1', {SomeClass obj -> println obj})
builder.add_method('setProperty2', {SomeClass obj -> this.property2 = obj})
builder.add_method('getProperty2', {return this.property2})
builder.add_method('method2', {return property1 + property2})
c = builder.get_instance()
i = c.newInstance()
i.property1 = new SomeClass()
i.property2 = 5
//i.method2() //throws GroovyCastException
//i.property2 = 'throws GroovyCastException'
//i.@property1 = 'throws MissingFieldException'
//No such field: property2 for class: MyClass
//i.@property2 = new SomeClass()
i.method1(new SomeClass())
//i.method1('throws MissingMethodException')
[编辑]
用例是这样的:我用Java定义接口或基类。用户在Groovy中实现接口或扩展基类,然后将该类传递回Java以供主应用程序使用。用户不是程序员,因此他们使用简单的DSL定义类,而我使用构建器构造实际的类。我仍在尝试使用Groovy
/ JRuby和Java interop(这两种语言都是新的)。