• jvm类文件结构解析(访问标志、异常)


    1、访问标志

    (1)概念

    紧接着常量池之后的两个字节,用于识别一些类或接口层次的访问信息,包括这个class是累还是接口、是否为public类型、abstract类型、类是否声明为final等

    (2)访问标志表:

    标志名称       标志值           含义
    ACC_PUBLIC    0x0001       是否为public类型
    ACC_FINAL     0x0010       是否被声明为final,只有类可设置
    ACC_SUPER     0x0020       是否允许使用invokespecial字节码指令的新语义,invokespecial指令的语意在JDK 1.0.2发生过改变,
    为了区别这条指令使用哪种语义,JDK 1.0.2之后编译出来的类的这个标志都必须为真 ACC_INTERFACE 0x0200 标识这是一个接口 ACC_ABSTRACT 0x0400 是否为abstract类型,对于接口或者抽象类来说,此标志值为真,其他类值为假 ACC_SYNTHETIC 0x1000 标识这个类并非由用户代码产生的 ACC_ANNOTATION 0x2000 标识这是一个注解 ACC_ENUM 0x4000 标识这是一个枚举

    (3)访问控制标志:

    紧跟常量池后面的部分:

     结合上面的表格,可以得出它是public修饰的,查看源码:

    public class Student {
        private String name;
        private Integer age;

    (4)类索引、父类索引与接口索引

    排列顺序为:类索引(u2)、父类索引(u2)与接口索引集合(第一项是u2类型的接口计数器,表示索引表的容量,即实现了几个接口,如果没有实现任何接口,则值为零,后面的接口索引不再占用任何字节),class文件由着三项来确定这个类的集成关系,如果有接口,后面还会有接口的信息。

     源码:

    public class mytest extends Thread implements Serializable,Comparable {

    (5)属性表结构和虚拟机规范预定义的属性:

    字段表结构:

    用于描述接口或者类中声明的变量,字段包括类级变量以及实例级变量,但是不包括在方法内部声明的局部变量,字段叫什么名字、字段被定义为什么类型都是无法固定的,所以只能引用常量池中的常量来描述。

    类型                  名称         数量
    u2               access_flags        1  访问控制符(如:public)
    u2               name_index          1  名字的索引(如:inc)
    u2               descriptor_index    1  描述符(如:())  -----public int inc()
    u2               attributes_count    1  
    attribute_info    attributes    attributes_count

    属性表:

    类型    名称    数量
    u2    attribute_name_index    1               属性名字的索引
    u4    attribute_length    1                   属性的长度
    u1    info    attribute_length                不等于2+4+1,等于 u2+u4+u1*190=196

    虚拟机预定义的属性:

     属性名称      使用位置    含义
     Code          方法表    Java代码编译成的字节码指令
     ConstantValue 字段表    final关键字定义的常量池
     Deprecated    类,方法,字段表    被声明为deprecated的方法和字段
     Exceptions    方法表     方法抛出的异常 
     EnclosingMethod    类文件     仅当一个类为局部类或者匿名类是才能拥有这个属性,这个属性用于标识这个类所在的外围方法 
     InnerClass    类文件     内部类列表 
     LineNumberTable    Code属性     Java源码的行号与字节码指令的对应关系 
     LocalVariableTable    Code属性     方法的局部便狼描述 
     StackMapTable    Code属性     JDK1.6中新增的属性,供新的类型检查检验器检查和处理目标方法的局部变量和操作数有所需要的类是否匹配 
     Signature    类,方法表,字段表      用于支持泛型情况下的方法签名
     SourceFile    类文件     记录源文件名称 
     SourceDebugExtension    类文件     用于存储额外的调试信息 
     Synthetic    类,方法表,字段表     标志方法或字段为编译器自动生成的 
     LocalVariableTypeTable    类     使用特征签名代替描述符,是为了引入泛型语法之后能描述泛型参数化类型而添加 
     RuntimeVisibleAnnotations    类,方法表,字段表     为动态注解提供支持 
     RuntimeInvisibleAnnotations    表,方法表,字段表     用于指明哪些注解是运行时不可见的 
     RuntimeVisibleParameterAnnotation    方法表     作用与RuntimeVisibleAnnotations属性类似,只不过作用对象为方法
     RuntimeInvisibleParameterAnnotation      方法表     作用与RuntimeInvisibleAnnotations属性类似,作用对象哪个为方法参数
     AnnotationDefault     方法表    用于记录注解类元素的默认值 
     BootstrapMethods    类文件     用于保存invokeddynamic指令引用的引导方式限定符  

    (6)方法的栈深和方法的本地变量数量

    2、异常

    (1)异常表:

    名称       类型     数量
    start_pc  u2       1
    end_pc    u2       1
    handle_pc u2      1
    catch_pc     u2    1

    (2)举例:

    00 00 00 04  00 08 00 02 ------0 4 8 #2

    异常的处理分为两种:throw和try....catch(代码块)

    0-4行出现异常则跳转到第十七行... ... 

     

     总结:

    (1)栈深和数量:

    栈深:stack

    本地变量数量:locals

    (2)参数:

    (3)元数据:描述类的数据

    (4)类名:不能超过256

  • 相关阅读:
    Curl Get请求&漏参数
    【Java基础】日期操作(返回当前日期&日期比较)
    【Java基础】生产者消费者模式
    [Groovy] 在Groovy中优雅的实现do while
    【转载】时间复杂度的度量
    [转载]Spring Cloud初探
    [Maven] 使用Maven管理多模块项目
    JS基础三
    JS基础部分(二)
    笔记不详细记录了,学完css之后做出下面分布的导航页
  • 原文地址:https://www.cnblogs.com/zhai1997/p/12565905.html
Copyright © 2020-2023  润新知