文档章节

【JVM虚拟机】(6)---深入理解Class中访问标志、类索引、父类索引、接口索引

o
 osc_gu9d45li
发布于 2019/04/09 19:32
字数 1857
阅读 0
收藏 0

精选30+云产品,助力企业轻松上云!>>>

<center> JVM(6)访问标志,类索引</center>

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

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

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

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

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

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

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

<font color=#FFD700> 一、概述</font>

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

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

<img src="https://img2018.cnblogs.com/blog/1090617/201904/1090617-20190409135031721-1835822396.jpg" style="border: 1px dashed rgb(204, 200, 200);" width="600" height="612">

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

<br>

<font color=#FFD700> 二、访问标志</font>

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

<img src="https://img2018.cnblogs.com/blog/1090617/201904/1090617-20190409135129522-1831389208.jpg" style="border: 1px dashed rgb(204, 200, 200);" width="700" height="412">

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

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

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

<img src="https://img2018.cnblogs.com/blog/1090617/201904/1090617-20190409135139548-792467058.png" style="border: 1px dashed rgb(204, 200, 200);" width="600" height="426">

<img src="https://img2018.cnblogs.com/blog/1090617/201904/1090617-20190409135148442-1272202826.jpg" style="border: 1px dashed rgb(204, 200, 200);" width="600" height="420">

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

2、public class修饰类

public class XiaoXiao {
  
}

在同一目录生成成class文件

javac XiaoXiao.java

在看反编译class文件

javap -v XiaoXiao.class

<img src="https://img2018.cnblogs.com/blog/1090617/201904/1090617-20190409135200951-1944917775.jpg" style="border: 1px dashed rgb(204, 200, 200);" width="600" height="274">

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

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

<img src="https://img2018.cnblogs.com/blog/1090617/201904/1090617-20190409135210605-118543476.jpg" style="border: 1px dashed rgb(204, 200, 200);" width="600" height="370">

完美吻合。

3、接口校验

public interface DaDa {

}

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

<img src="https://img2018.cnblogs.com/blog/1090617/201904/1090617-20190409135219909-386750991.jpg" style="border: 1px dashed rgb(204, 200, 200);" width="600" height="247">

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

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

<img src="https://img2018.cnblogs.com/blog/1090617/201904/1090617-20190409135232383-1170041644.jpg" style="border: 1px dashed rgb(204, 200, 200);" width="600" height="218">

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

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

<img src="https://img2018.cnblogs.com/blog/1090617/201904/1090617-20190409135241834-913919387.jpg" style="border: 1px dashed rgb(204, 200, 200);" width="600" height="410">

<br>

<font color=#FFD700> 三、类索引、父类索引、接口索引 </font>

1、概念

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

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

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

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

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

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

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

1、普通类测试

public class XiaoXiao {
  
}

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

<img src="https://img2018.cnblogs.com/blog/1090617/201904/1090617-20190409135252392-556980563.jpg" style="border: 1px dashed rgb(204, 200, 200);" width="600" height="425">

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

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

<img src="https://img2018.cnblogs.com/blog/1090617/201904/1090617-20190409135305029-1927119339.jpg" style="border: 2px dashed rgb(204, 200, 200);" width="600" height="273">

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

完美!

2、实现接口测试

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

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

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

<img src="https://img2018.cnblogs.com/blog/1090617/201904/1090617-20190409135321017-796665369.jpg" style="border: 2px dashed rgb(204, 200, 200);" width="600" height="385">

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

在打开16进制文件。

<img src="https://img2018.cnblogs.com/blog/1090617/201904/1090617-20190409135331220-1772694961.jpg" style="border: 2px dashed rgb(204, 200, 200);" width="600" height="260">

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

在看反编译后的class文件。

<img src="https://img2018.cnblogs.com/blog/1090617/201904/1090617-20190409135343028-161944163.jpg" style="border: 2px dashed rgb(204, 200, 200);" width="600" height="286">

验证成功!

##<font color=#FFD700>参考 </font>

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

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

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

下一篇: IDEA 2019注册码
o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
【JVM虚拟机】(7)---深入理解Class中-属性集合

<center>深入理解Class中-属性集合</center> 之前有关class文件已经写了两篇博客: 1、【JVM虚拟机】(5)---深入理解JVM-Class中常量池 2、【JVM虚拟机】(6)---深入理解Class中访问标志、类索...

osc_xgk2otgu
04/16
2
0
【JVM虚拟机】(8)--深入理解Class中--方法、属性表集合

#<center>深入理解Class中--方法、属性表集合</center> 之前有关class文件已经写了两篇博客: 1、【JVM虚拟机】(5)---深入理解JVM-Class中常量池 2、【JVM虚拟机】(6)---深入理解Class中访问...

osc_wa6zijqd
2019/04/18
2
0
详解Class类文件的结构(下)

接着上一篇文章讲:详解Class类文件的结构(上) 本文继续使用上次的Test.class文件,它是由下面单独的一个类文件编译而成的,没有包。 6. 索引(Index) 索引又分类索引、父类索引和接口索引...

beifengtz
2019/06/17
0
0
深入理解Java虚拟机(类文件结构)

本文分享自微信公众号 - BaronTalk(BaronTalk)。 如有侵权,请联系 support@oschina.cn 删除。 本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。...

张磊
2019/06/12
0
0
【学习笔记】深入理解Java虚拟机 第六章 类文件结构(Class类文件的结构)

任何一个Class文件都对应着唯一 一个类或接口的定义信息,但反过来说,类或接口并不一定都得定义在文件里(譬如类或接口也可以通过类加载器直接生成)。 Class文件是一组以8位字节为基础单位...

osc_uyb9f22c
01/01
2
0

没有更多内容

加载失败,请刷新页面

加载更多

038. RocketMQ 高性能最佳实践

1. 最佳实践之 Producer 1. 一个应用尽可能用一个 Topic,消息子类型用 tags 来标识,tags 可以由应用自由设置。 只有发送消息设置了 tags,消费方在订阅消息时,才可以利用 tags 在 broker...

华夏紫穹
26分钟前
24
0
QQ音乐Android客户端Web页面通用性能优化实践

QQ音乐 Android 客户端的 Web 页面日均 PV 达到千万量级,然而页面的打开耗时与 Native 页面相距甚远,需要系统性优化。本文将介绍 QQ 音乐 Android 客户端在进行 Web 页面通用性能优化过程中...

腾讯云开发者社区
45分钟前
24
0
rabbitmq+sleuth+zinkip 分布式链路追踪

我们都知道,微服务之间通过feign传递,在复杂的微服务架构系统中,几乎每一个前端请求都会形成一个复杂的分布式服务调用链路,在每条链路中任何一个依赖服务出现延迟超时或者错误都有可能引...

良许Linux
今天
12
0
5分钟搭建属于你的视频会议系统

前言 在疫情的推动下视频会议和线上办公大力发展,如果你也想了解视频会议,看看这篇文章吧 准备工作 一台Ubuntu18.04拥有公网IP的服务器 一个域名提前解析到这台服务器上 安全组设置规则tcp...

死磕音视频
今天
17
0
从文本JavaScript中删除HTML - Strip HTML from Text JavaScript

问题: 有没有一种简单的方法可以在JavaScript中获取html字符串并去除html? 解决方案: 参考一: https://stackoom.com/question/3RxM/从文本JavaScript中删除HTML 参考二: https://oldbug...

fyin1314
今天
19
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部