• ASM案例


    前言#

    asm是操作class字节码的框架,常常用于运行期修改字节码实现特定功能, 比如aop, 比如jacoco的覆盖率插桩.
    这次的需求是通过class文件去判断是否是枚举类.
    如何通过asm读一个class文件呢?

    public static void main(String[] args) {
    		try {
    			FileInputStream in = new FileInputStream("D://StatusTypeEnum.class");
    			ClassReader cr = new ClassReader(in);
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    

    import jdk.internal.org.objectweb.asm.ClassReader; jdk内置了asm相关的操作类,所以非常方便.
    如何看是不是枚举类
    思路:

    1. 枚举类是默认继承了 java.lang.Enum, 查看父类
    ClassReader cr = new ClassReader(in);
    String superName = cr.getSuperName();
    

    实际上不够正确, 因为Enum类也可以在实现别的接口.
    2)通过Access_Flags去查看.

    ClassReader cr = new ClassReader(in);
    int access = cr.getAccess();
    

    access_flags 描述的是当前类(或者接口)的访问修饰符, 如public, private等,(参考: https://blog.csdn.net/u014490683/article/details/22745799)
    我们用javap -v StatusTypeEnum.class 解析当前类的字节码,得到如下:

    public final class StatusTypeEnum extends java.lang.Enum<StatusTypeEnum> 
    minor version: 0 
    major version: 54 
    flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_ENUM
    

    看到没, 有4个flags, 调用Opcodes.ACC_PUBLIC 就可以看到这个int值是多少.

    int ACC_PUBLIC = 1;
        int ACC_PRIVATE = 2;
        int ACC_PROTECTED = 4;
        int ACC_STATIC = 8;
        int ACC_FINAL = 16;
        int ACC_SUPER = 32;
        int ACC_SYNCHRONIZED = 32;
        int ACC_VOLATILE = 64;
        int ACC_BRIDGE = 64;
        int ACC_VARARGS = 128;
        int ACC_TRANSIENT = 128;
        int ACC_NATIVE = 256;
        int ACC_INTERFACE = 512;
        int ACC_ABSTRACT = 1024;
        int ACC_STRICT = 2048;
        int ACC_SYNTHETIC = 4096;
        int ACC_ANNOTATION = 8192;
        int ACC_ENUM = 16384;
        int ACC_MANDATED = 32768;
        int ACC_DEPRECATED = 131072;
    

    实际上,cr.getAccess()的返回值在这个例子中就会是cr.getAccess()=Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL+ Opcodes.ACC_SUPER+ Opcodes.ACC_ENUM
    也就是16433.
    你会发现flags的值会是2倍关系,只有这样设置才能从一个access值反推出唯一的flags.(在linux系统的rwx权限里也有异曲同工之妙)
    那么,现在如何去判断一个类是抽象类?相比你已经会了.

    转载请注明来源,谢谢
  • 相关阅读:
    【转】Python常见web系统返回码
    【转】暴力破解无线WiFi密码
    【转】Django继承AbstractUser新建User Model时出现auth.User.groups: (fields.E304)错误
    Python去除文件中的空格、Tab键和回车
    用filter求素数
    【转】Python读取PDF文档,输出内容
    【转】RPC简单介绍
    【转】Python3使用Django2.x的settings文件详解
    Python生成随机字符串
    Python之turtle画同心圆和棋盘
  • 原文地址:https://www.cnblogs.com/zhhiyp/p/10447579.html
Copyright © 2020-2023  润新知