我正在尝试在Groovy中动态生成类。我的方法是:
class MetaClassTest {
static class TestClass {
String getName() {
return "Jake"
}
}
public static void main(String[] args) {
def testClass = TestClass
def metaMethod = testClass.metaClass.getMetaMethod('getName', [] as Class[])
testClass.metaClass.getName = {
metaMethod.invoke(delegate) + " and the Fatman"
}
assert testClass.newInstance().name == "Jake and the Fatman"
}
}
然而,这改变了原始类的行为,这是我不想要的。所以我的问题是:
如何动态克隆(并可能重命名)现有类,以便我能够创建多个派生?
答案 0 :(得分:1)
您可以覆盖类实例方法:
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="72dp"
android:height="66dp"
android:viewportHeight="66"
android:viewportWidth="72">
<path
android:fillColor="@android:color/transparent"
android:pathData="M 0.00 0.00 L 72.00 0.00 L 72.00 66.00 L 0.00 66.00 L 0.00 0.00 Z" />
<path
android:fillColor="#F7592B"
android:pathData="M 20.99 1.04 C 26.30 1.45 30.97 4.88 36.04 5.70 C 40.02 5.23 43.79 2.79 47.70
1.80 C 56.08 -0.90 65.46 4.21 69.03 11.97 C 71.67 17.65 71.59 24.74 70.62 30.81
C 68.57 41.48 60.32 50.55 51.81 56.81 C 47.69 59.73 43.11 62.72 38.21 64.12 C
34.80 65.13 31.23 63.34 28.24 61.86 C 19.69 57.27 11.77 50.76 6.25 42.72 C 0.82
34.78 -0.33 24.87 1.66 15.60 C 3.69 7.15 12.14 0.18 20.99 1.04 Z" />
<path
android:fillColor="#1721dc"
android:pathData="M 19.98 7.14 C 25.68 7.39 30.87 12.07 36.10 12.99 C 41.30 12.15 46.97 7.14 52.84
7.35 C 58.72 7.85 63.41 12.52 64.67 18.17 C 65.71 23.40 65.21 29.32 63.25 34.30
C 59.83 42.88 52.20 49.81 44.38 54.43 C 40.52 56.53 36.81 58.58 32.37 56.70 C
24.56 53.51 17.02 47.75 12.20 40.77 C 7.31 33.87 5.58 24.79 7.64 16.59 C 9.15
11.09 14.21 6.98 19.98 7.14 Z" />
</vector>
答案 1 :(得分:0)
我不确定以下是否有效,但可能值得一试:你能检查一下你是否可以以某种方式深度复制TestClass,然后修改唯一的克隆类?以下可能会派上用场:
也许groovy lang metaprogramming可以在元编程上寻找更多信息。
答案 2 :(得分:0)
到目前为止,最透明(尽管仍然很脏)的解决方案已在此处暗示过。我可以使用GroovyClassLoader.parse()
方法创建子类骨架,然后通过metaClass
对其进行丰富。
class TestClass {
String getName() {
return "Jake"
}
}
def parentClass = TestClass
def groovyClassLoader = new GroovyClassLoader(parentClass.classLoader)
def childClass1 = groovyClassLoader.parseClass("class ChildClass1 extends ${ parentClass.canonicalName } {}")
def oldGetName1 = childClass1.metaClass.getMetaMethod('getName', [] as Class[])
childClass1.metaClass.getName = {
oldGetName1.invoke(delegate) + " and the Fatman"
}
def childClass2 = groovyClassLoader.parseClass("class ChildClass2 extends ${ parentClass.canonicalName } {}")
def oldGetName2 = childClass2.metaClass.getMetaMethod('getName', [] as Class[])
childClass2.metaClass.getName = {
oldGetName2.invoke(delegate) + " the Dog"
}
assert childClass1.newInstance().name == "Jake and the Fatman"
assert childClass2.newInstance().name == "Jake the Dog"
我在运行时动态创建类的原因是,应用程序可以使用Groovy DSL脚本进行扩展,这些脚本通常由几乎没有任何编程技能的人编写。