JVM(6)访问标志,类索引

上一篇博客讲【JVM虚拟机】(5)---深入理解JVM-Class中常量池

我们知道一个class文件正常可以分为7个部分:

  • 魔数与class文件版本
  • 常量池
  • 访问标志
  • 类索引、父类索引、接口索引
  • 字段表集合
  • 方法表集合
  • 属性表集合

那么这篇博客主要讲有关 访问标志类索引、父类索引、接口索引 相关的理解和代码示例。

先通俗的说下这两个的作用:

访问标志: 告知该类是一个什么类型的类,是普通类?还是接口?还是枚举?或者其它类,是用什么修饰符修饰该类的。

类索引、父类索引、接口索引: 告知该类全限名的常量池地址,有继承的话父类全限名的常量池地址,实现接口的话接口全限名的常量池地址(接口可以多个)。

一、概述

先对上篇博客做个补充:上篇博客虽然说了常量池但对class整体文件结构并没有说清楚,其实一个class文件即

.class 文件本质上就是一张,由下表所示的数据项构成。

上图也就是一开始所讲的7个部分组成。

二、访问标志

有关访问标志找了很多资料,也看了《深入了解java虚拟机》书中第六章给的有关访问标志的信息,网上几乎讲访问标志都是下面这张图,然后写个pulic class 类 一测试,果然是0021 代表 ACC_PUBLIC+ACC_SUPER 这样一看是没毛病。但是都没有再写一个接口来验证的,如果自己写个接口就会发现下面我圈红的地方说,JDK1.2后该处必须为真 是不对的。先看图。

1、访问标志转为16进制解释

思考:就好比为什么ACC_PUBLIC是00 01?如何产生的呢。

访问标志实际上就是一系列组合,因为有16位所以共有16个标志可以使用,但是目前就定义了8个,剩下的估计是给jdk9和10......预留的吧。这8个如图所示。


讲完理论,接下来我们进行代码测试,为了校验更佳准确我写个普通类和接口分别测试:

2、public class修饰类

public class XiaoXiao {

}

在同一目录生成成class文件

javac XiaoXiao.java

在看反编译class文件

javap -v XiaoXiao.class

我们发现这里flags为: ACC_PUBLIC, ACC_SUPER,那这么推算那么十六进制应该是0021。

那我们再来查看XiaoXiao.class的十六进制数据

完美吻合。

3、接口校验

public interface DaDa {

}

同样先生成class文件在反编译class文件

看图我们可以发现flags值为:ACC_PUBLIC, ACC_INTERFACE, ACC_ABSTRACT ,这个也很好理解接口本身就是抽象类。那么加起来就是0601。但这里和上图有点不符的地方就是图中说ACC_SUPER只要是JDK1.2必须为真,而这里明显不为真,所以有关这点并不准确。

那我们再将class文件转位16进制验证。

这么一来验证也是通过的。

有关ACC_SUPER不准确的问题,应该是ACC_SUPER不会是在JDK1.2以后必须为真,应该如下描述:

三、类索引、父类索引、接口索引

1、概念

在 .class 文件中由这三项数据来确定这个的继承关系。

1、类索引:u2 数据类型,用于确定这个类的全限定名。

2、父类索引:u2 数据类型,用于确定这个类的父类的全限定名。

3、接口索引:u2 数据类型的集合,用于描述类实现了哪些接口,这些被实现的接口将按照 implements 语句后的顺序从左至右排列在接口索引集合中。

接口索引集合分为两部分,第一部分表示接口计数器(interfaces_count),是一个 u2 类型的数据,第二部分是接口索引表表示接口信息,紧跟在接口计数器之后。

若一个类实现的接口为 0,则接口计数器的值为 0,接口索引表不占用任何字节。

同样这里测试写两个测试类来测试。

1、普通类测试

public class XiaoXiao {

}

同样生成class文件,然后查看16进制数据

我们看到该类的类索引在常量池0002位置 ,父类索引在常量池0003位置,接口为0000代表该类没有实现任何接口。

然后我们在反编译XiaoXiao.class文件,方便我们查找常量池。

真的是一目了然,常量池0002就是当前类,0003父类为默认继承了老祖宗Object。

完美!

2、实现接口测试

为了更加深刻理解,这里再写一个类实现两个接口的类,在来查看。

//接口
public interface DaDa {
}
//接口
public interface LaLa {
}
//类实现上面两个接口
public class XiaoXiao implements DaDa ,LaLa{
}

说明:这里不能通过 javac XiaoXiao.java生成XiaoXiao.class文件了,因为会报错。我分析原因是因为你手动编译是无法找到DaDa ,LaLa编译信息。

所以我们可以把整个项目启动后,到target目录下去找该class文件就可以。

在打开16进制文件。

我们看到该类的类索引在常量池0002位置 ,父类索引在常量池0003位。接口为0002代表该类实现了两个接口,一个接口在常量池位置004,一个在常量池位置0005。

在看反编译后的class文件。

验证成功!

参考

1、深入了解java虚拟机第2版第六章

2、深入理解JVM-Class文件结构和类加载

只要自己变优秀了,其他的事情才会跟着好起来(少将4)

【JVM虚拟机】(6)---深入理解Class中访问标志、类索引、父类索引、接口索引的更多相关文章

  1. [转]深刻理解Python中的元类(metaclass)以及元类实现单例模式

    使用元类 深刻理解Python中的元类(metaclass)以及元类实现单例模式 在看一些框架源代码的过程中碰到很多元类的实例,看起来很吃力很晦涩:在看python cookbook中关于元类创建单例 ...

  2. cc31a_demo--CppPrimer_静态成员与继承-在派生类中访问基类中的static成员的方法

    //*基类中的static成员,在整个继承层次中只有一个实例 //*在派生类中访问基类中的static成员的方法 //1.基类名::成员名 //2.子类名::成员名 //3.对象.成员名 //4.指针 ...

  3. 深刻理解Python中的元类(metaclass)以及元类实现单例模式

    在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大多数编程语言中,类就是一组用来描述如何生成一个对象的代码段.在Python中这一点仍 ...

  4. 深刻理解Python中的元类metaclass(转)

    本文由 伯乐在线 - bigship 翻译 英文出处:stackoverflow 译文:http://blog.jobbole.com/21351/ 译注:这是一篇在Stack overflow上很热 ...

  5. 深刻理解Python中的元类(metaclass)

    译注:这是一篇在Stack overflow上很热的帖子.提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自省有关,但仍然觉得 ...

  6. [转] 深刻理解Python中的元类(metaclass)

    非常详细的一篇深入讲解Python中metaclass的文章,感谢伯乐在线-bigship翻译及作者,转载收藏. 本文由 伯乐在线 - bigship 翻译.未经许可,禁止转载!英文出处:stacko ...

  7. 深刻理解Python中的元类(metaclass)【转】

    译注:这是一篇在Stack overflow上很热的帖子.提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自省有关,但仍然觉得 ...

  8. 深入理解Python中的元类(metaclass)

    原文 译注:这是一篇在Stack overflow上很热的帖子.提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自省有关,但仍 ...

  9. 深度理解python中的元类

    本文转自:(英文版)https://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python   (翻译版)   http:// ...

随机推荐

  1. Leetcode_删除排序数组中的重复项

    Leetcode  删除排序数组中的重复项 题目: 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度. 不要使用 额外的数组空间,你必须在原地修改输入数 ...

  2. flush()清空文件缓存区

    # 缓冲区:cpu 一级缓存 二级缓存 三级缓存 import time f =open('2.txt','a+' ,encoding='utf-8') f.write('helloworld\n') ...

  3. windows下安装mysql-5.7.11-winx64

    1.解压.   2.将『D:\Program Files\mysql-5.7.11-winx64\bin』加入系统环境变量.   3.修改my-default.ini.   4.初始化data目录,在 ...

  4. Java 使用BigDecimal类处理高精度计算

    Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算.双精度浮点型变量double可以处理16位有效数,但在实际应用中,可能需要对更大或者更小的 ...

  5. maven工程,java代码加载resources下面资源文件的路径

    1 通过类加载器加载器, 1. URL resource = TestMain.class.getResource("/18500228040.txt");File file = ...

  6. mysql性能调优与架构设计笔记

    1.mysql基本介绍 mysql支持多线程高并发的关系型数据库; 数据库存储引擎InnoDB.MyISAM; mysql快速崛起的原因就是他是开源的; 性能一直是mysql自豪的一大特点; 2.my ...

  7. 最好的营销是“调情”

    每一个精彩的营销案例都应该像一个精彩的故事,而故事最精彩的讲述方式就是设置一个开放的结局,把解读和诠释的权利留给读者和观众.宣讲.洗脑式的营销时代已经终结,就像单相思的深情表白永远不如两情相悦的彼此挑 ...

  8. 爬虫-Python爬虫常用库

    一.常用库 1.requests 做请求的时候用到. requests.get("url") 2.selenium 自动化会用到. 3.lxml 4.beautifulsoup 5 ...

  9. 对try-catch-finally异常处理的最新理解

    try{ ...... }catch(......){ }finally{ ...... } 这个结构是用来处理Java所有可能出现的异常的,这个我很早其实就已经学过,不过最近看了个视频,感觉自己虽然 ...

  10. unwrapThrowable

    package org.apache.ibatis.reflection; import java.lang.reflect.InvocationTargetException; import jav ...