java - 生成没有默认构造函数的类的子类

标签 java java-bytecode-asm cglib

我需要使用 cglib 为没有默认构造函数的类生成子类。我有以下代码,适用于具有默认构造函数的类:

    Enhancer enhancer = new Enhancer();
    enhancer.setCallbackType(NoOp.class);
    enhancer.setUseCache(false);

    enhancer.setSuperclass(clazz);
    return enhancer.createClass();

新类应该有默认构造函数,需要从其父类(super class)调用一些非默认构造函数。

我搜索了一下,发现cglib不能做这样的事情,我需要使用asm。但是我找不到向类添加默认构造函数的示例。

如果有人有一个如何实现它的示例,那就太好了。

最佳答案

我解决了这个问题。看起来和我之前想象的有点不一样。 Cglib 继承了所有构造函数,而不仅仅是我之前认为的默认构造函数。

但是,我似乎无法在不影响现有 cglib 构造函数构造代码的情况下替换构造函数。这是次要的影响,所以我只是从构造函数注入(inject)转向方法注入(inject)。我在构造函数返回之前添加我的方法调用。这有效!我对此感到非常高兴。

这就是我得到的:

cglib 增强器调用

Enhancer enhancer = new Enhancer();
        enhancer.setNamingPolicy(new IndexedNamingPolicy());
        enhancer.setCallbackType(NoOp.class);
        enhancer.setUseCache(false);
        enhancer.setStrategy(new DefaultGeneratorStrategy() {
            @Override
            protected ClassGenerator transform(ClassGenerator cg) throws Exception {
                return new TransformingClassGenerator(cg, new DefaultConstructorEmitter(key));
            }
        });

        enhancer.setSuperclass(clazz);
        return enhancer.createClass();

和我的 DefaultConstructorEmitter (呵呵,它仍然是为构造函数处理而命名的,没关系)

private class DefaultConstructorEmitter extends ClassEmitterTransformer {
        private final Signature CALL_SIGNATURE = TypeUtils.parseSignature("void someMethod(Object)");

        private String parametersKey;

        public DefaultConstructorEmitter(final String key) {
            parametersKey = key;
        }

        @Override
        public CodeEmitter begin_method(int access, Signature sig, Type[] exceptions) {
            final CodeEmitter emitter = super.begin_method(access, sig, exceptions);
            if (sig.getName().equals(Constants.CONSTRUCTOR_NAME)) {
                return new CodeEmitter(emitter) {
                    @Override
                    public void visitInsn(int arg0) {
                        if (arg0 == Opcodes.RETURN) {
                            Type classType = ...   
                            emitter.load_this();
                            emitter.push(parametersKey);
                            emitter.invoke_static(classType, CALL_SIGNATURE);
                        }
                        super.visitInsn(arg0);
                    }
                };
            }

            return emitter;
        }
    }

希望这个例子能帮助别人不要像我一样花费几个小时。

关于java - 生成没有默认构造函数的类的子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14858493/

相关文章:

java - 使用 cglib 或 javaassist 哪一个

android - 在 Android 上使用 Groovy

java - java中Json预处理

java - 使用 ASM 字节码转换时 java.lang.instrument 中出现堆栈溢出错误

java - ASM - 如何从 Java 字节码名称转换 Java 类名称?

java - 在我的项目包之外的类上使用asm(java字节码)类读取器?

cglib - 关于CGLIB中的各种回调

java - 使用编程配置 hibernate ,启动 hibernate.hbm2ddl.auto

java - 下面的程序将如何工作?

java - 添加枚举值?