0

这是一个hello world级别的groovy mop程序,只是想MetaClassImpl用我自己的自定义,但似乎groovy不允许,这是我的代码:

MyMetaClassImpl.java

import groovy.lang.MetaClassImpl;

public class MyMetaClassImpl extends MetaClassImpl {
    public MyMetaClassImpl(Class theClass) {
        super(theClass);
    }

    @Override
    public Object invokeMethod(Object object, String methodName, Object[] originalArguments) {
        System.out.println("invoke here");
        return super.invokeMethod(object, methodName, originalArguments);
    }
}

Person.groovy

class Person {
    String name
    int age

    String getHabit(String name) {
        String habit = null
        switch (name) {
            case "ZhangSan":
                habit = "soccer"
                break
            case "Lisi":
                habit = "basketball"
                break
            default:
                break
        }
        return habit
    }

    @Override
    Object invokeMethod(String name, Object args) {
        if (name == 'say') {
            println "say method has been invoked"
            return null;
        }
        super.invokeMethod(name, args)
    }
}

PersonGroovyMain.groovy

import cn.crabime.java.meta.MyDelegateMetaClass
import cn.crabime.java.meta.MyMetaClassImpl
import cn.crabime.java.pogo.Person
import org.codehaus.groovy.runtime.InvokerHelper

class PersonGroovyMain {

    static void main(String[] args) {
        invokeNormal()
        
        // cause error line
        def p = new Person()
        println p

    }

    static MetaClassImpl invokeNormal() {
        MyMetaClassImpl norMetaClass = new MyMetaClassImpl(Person.class)
        norMetaClass.initialize()
        InvokerHelper.metaRegistry.setMetaClass(Person.class, norMetaClass)
        return norMetaClass
    }
}

下面的输出错误:

Exception in thread "main" groovy.lang.GroovyRuntimeException: Could not find matching constructor for: cn.crabime.java.pogo.Person()
    at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1724)
    at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:1527)
    at org.codehaus.groovy.runtime.callsite.MetaClassConstructorSite.callConstructor(MetaClassConstructorSite.java:46)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:57)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:230)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:234)
    at cn.crabime.java.main.PersonGroovyMain.main(PersonGroovyMain.groovy:17)

这个问题已经困扰我两天了,我不想用DelegatingMetaClass,希望有人能帮助我。

4

1 回答 1

1

使用带有 3 个参数的构造函数

@groovy.transform.ToString
class A{ String name }

def meta = new MetaClassImpl(GroovySystem.getMetaClassRegistry(), A.class, null){
    @Override
    public Object invokeMethod(Object object, String methodName, Object arguments) {
        if(methodName=='f1' && !arguments){
            return object.name.toUpperCase()
        }
        return super.invokeMethod(object, methodName, arguments)
    }
}
meta.initialize()
GroovySystem.getMetaClassRegistry().setMetaClass(A.class, meta)

def a = new A(name:'world')
println a.f1()
于 2021-07-25T17:14:33.637 回答