ASM核心API-元数据

AMS4使用指南
实战java虚拟机

泛型

类使用泛型
在类定义当中使用范型时,需要增加Signature字段来添加范型信息。该Signature的组成是“<范型参数名:范型扩展的类:范型扩展的接口…>父类描述接口描述”

cw.visit(V1_7, ACC_PUBLIC, clazzPath, "<T:Ljava/lang/String;G:Ljava/lang/Date;>Ljava/lang/Thread;Ljava/lang/AutoCloseable;", "java/lang/Thread", new String[] { "java/lang/AutoCloseable"});

结果

package cn.asm;

public class Generic<T extends String, G extends Date> extends Thread implements AutoCloseable {
}

字段使用泛型

cw.visitField(ACC_PRIVATE, "cache","Ljava/util/Map;", "Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;", null).visitEnd();

结果

  private Map<String, Object> cache;

方法使用泛型

 cw.visitMethod(ACC_PUBLIC, "getList","(Ljava/util/Map;)Ljava/util/List;","(Ljava/util/Map<Ljava/lang/String;Ljava/lang/Integer;>;)Ljava/util/List<Ljava/lang/String;>;",null).visitEnd();

结果

  public List<String> getList(Map<String, Integer> var1) {
    }

这里写图片描述

SignatureVisitor

public abstract class SignatureVisitor {
    public final static char EXTENDS = ’+’;
    public final static char SUPER = ’-’;
    public final static char INSTANCEOF = ’=’;
    public SignatureVisitor(int api);
    public void visitFormalTypeParameter(String name);
    public SignatureVisitor visitClassBound();
    public SignatureVisitor visitInterfaceBound();
    public SignatureVisitor visitSuperclass();
    public SignatureVisitor visitInterface();
    public SignatureVisitor visitParameterType();
    public SignatureVisitor visitReturnType();
    public SignatureVisitor visitExceptionType();
    public void visitBaseType(char descriptor);
    public void visitTypeVariable(String name);
    public SignatureVisitor visitArrayType();
    public void visitClassType(String name);
    public void visitInnerClassType(String name);
    public void visitTypeArgument();
    public SignatureVisitor visitTypeArgument(char wildcard);
    public void visitEnd();
}

注解

类、字段、方法和方法参数注释,比如@Deprecated 或@Override,
只要它们的保留策略不是 RetentionPolicy.SOURCE,它们就会被存储在编译后的类中,这一信息不是在运行时供字节代码指令使用。
但是,如果保留策略是 RetentionPolicy.RUNTIME,则可以通过反射 API 访问它。它还可以供编译器使用。
定义注解
定义注解acc必须包含ACC_ANNOTATION|ACC_INTERFACE,以及必须继承java/lang/annotation/Annotation接口。

ClassWriter cw = new ClassWriter(0);
//定义注解信息:
cw.visit(V1_7, ACC_PUBLIC|ACC_ANNOTATION|ACC_INTERFACE, clazzPath, null, "java/lang/Object", new String[]{ "java/lang/annotation/Annotation" });

//注解属性 cacheable
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, "cacheable","()Z", null, null);
AnnotationVisitor av = mv.visitAnnotationDefault();
av.visit(null,false);
mv.visitEnd();

//注解属性 key
mv = cw.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, "key","()Ljava/lang/String;", null, null);
mv.visitEnd();

运行结果:

public @interface Anno {
    boolean cacheable() default false;

    String key();
}

使用注解
注意:不校验注解类是否存在,也不校验属性是否存在,也不校验类型是否匹配

//类上是用注解。
AnnotationVisitor av = cw.visitAnnotation("cn/Anno",false);
av.visit("cacheable",1);//与定义的值类型不匹配
av.visit("noexistkey","aa"); //不存在的key
av.visitEnd();

//方法上是用注解
MethodVisitor.visitAnnotation("cn/Anno",false);

//字段上是用注解
FieldVisitor.visitAnnotation("cn/Anno",false);

AnnotationVisitor

public abstract class AnnotationVisitor {
    public AnnotationVisitor(int api);
    public AnnotationVisitor(int api, AnnotationVisitor av);
    public void visit(String name, Object value);
    public void visitEnum(String name, String desc, String value);
    public AnnotationVisitor visitAnnotation(String name, String desc);
    public AnnotationVisitor visitArray(String name);
    public void visitEnd();
}

工具

  • TraceAnnotationVisitor
  • CheckAnnotationAdapter

枚举

枚举

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值