使用ASM实现接口

字节码

依赖

 <!--
    <dependency>
      <groupId>org.ow2.asm</groupId>
      <artifactId>asm-all</artifactId>
      <version>5.2</version>
    </dependency>

    <dependency>
    <groupId>asm</groupId>
    <artifactId>asm-all</artifactId>
    <version>3.3.1</version>
    </dependency>
    -->

    <dependency>
      <groupId>org.ow2.asm</groupId>
      <artifactId>asm</artifactId>
      <version>7.1</version>
    </dependency>

    <dependency>
      <groupId>org.ow2.asm</groupId>
      <artifactId>asm-commons</artifactId>
      <version>7.1</version>
    </dependency>

    <!--
    <dependency>
    <groupId>org.ow2.asm</groupId>
    <artifactId>asm-util</artifactId>
    <version>7.1</version>
    </dependency>

    <dependency>
      <groupId>org.ow2.asm</groupId>
      <artifactId>asm-test</artifactId>
      <version>7.1</version>
    </dependency>
    -->

接口

public interface Person {
    boolean getBoolean();
    char getChar();
    byte getByte();
    short getShort();
    int getInt();
    float getFloat();
    double getDouble();
    long getLong();
    String getName();
    void setId();
    int add(int a, int b);
    Student getStudent(char[] vv);
    Student[] getStudents(char[] vv);
    Long getL();
    Double getD();
    MyEnum getMyEnum();
}

代码

import org.objectweb.asm.*;
import org.objectweb.asm.commons.AdviceAdapter;

import java.io.FileOutputStream;
import java.lang.reflect.Method;

public class AsmUtil implements Opcodes {

    private static byte[] generateByteCode(Class<?> clazz) throws Exception {

        ClassReader classReader = new ClassReader(clazz.getName());
        ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        ClassVisitor interfaceClassVisitor = new InterfaceClassVisitor(classWriter, clazz);
        classReader.accept(interfaceClassVisitor, ClassReader.SKIP_DEBUG);
        //写入文件
        byte[] code = classWriter.toByteArray();
        /**
         *         此3句打开会在当前生成一个class文件
         *         FileOutputStream fos = new FileOutputStream(getNewClassName(clazz) + ".class");
         *         fos.write(code);
         *         fos.close();
         */
        return code;
    }

    private static class InterfaceClassVisitor extends ClassVisitor {
        private Class<?> clazz;

        public InterfaceClassVisitor(ClassVisitor classVisitor, Class<?> clazz) {
            super(ASM7, classVisitor);
            this.clazz = clazz;
        }

        @Override
        public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
            String className = getNewClassName(clazz);
            cv.visit(V1_8, ACC_PUBLIC, className, null, "java/lang/Object", new String[]{clazz.getName().replaceAll("\\.", "/")});

            //生成默认构造函数
            MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
            mv.visitCode();
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
            mv.visitInsn(RETURN);
            mv.visitMaxs(0, 0);
            mv.visitEnd();
        }

        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
            if ("<init>".equals(name)) {
                MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions);
                return methodVisitor;
            }
            MethodVisitor mv = cv.visitMethod(access - ACC_ABSTRACT, name, desc, signature, exceptions);
            return new MethodAdviceAdapter(mv, access, name, desc);
        }
    }

    private static class MethodAdviceAdapter extends AdviceAdapter {
        private String descriptor;

        protected MethodAdviceAdapter(MethodVisitor methodVisitor, int access, String name, String descriptor) {
            super(ASM7, methodVisitor, access, name, descriptor);
            this.descriptor = descriptor;
        }

        @Override
        public void visitEnd() {
            if (descriptor.endsWith("V")) {
                mv.visitInsn(RETURN);
            } else if (descriptor.endsWith("I") || descriptor.endsWith("Z") || descriptor.endsWith("C") || descriptor.endsWith("B") || descriptor.endsWith("S")) {
                mv.visitInsn(ICONST_0);
                mv.visitInsn(IRETURN);
            } else if (descriptor.endsWith("F")) {
                mv.visitInsn(FCONST_0);
                mv.visitInsn(FRETURN);
            } else if (descriptor.endsWith("D")) {
                mv.visitInsn(DCONST_0);
                mv.visitInsn(DRETURN);
            } else if (descriptor.endsWith("J")) {
                mv.visitInsn(LCONST_0);
                mv.visitInsn(LRETURN);
            } else {
                mv.visitInsn(ACONST_NULL);
                mv.visitInsn(ARETURN);
            }
            mv.visitMaxs(0, 0);
            super.visitEnd();
        }
    }

    public static Class getInterfaceImpl(Class clazz) throws Exception {
        byte[] code = generateByteCode(clazz);
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        Class cls = Class.forName("java.lang.ClassLoader");
        Method method = cls.getDeclaredMethod("defineClass", new Class[]{String.class, byte[].class, int.class, int.class});
        method.setAccessible(true);
        try {
            Object[] args = new Object[]{getNewClassName(clazz), code, 0, code.length};
            clazz = (Class) method.invoke(loader, args);
            return clazz;
        } finally {
            method.setAccessible(false);
        }
    }

    private static String getNewClassName(Class<?> clazz) {
        return clazz.getSimpleName() + "Impl";
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值