Jvm(36),class文件结构----访问标志

access_flags中一共有32个标志位可以使用,当前只定义了其中的8个,没有使用到的标志位要求一律为0。

package org.fenixsoft.clazz; public class TestClass{ private int m; public int inc(){ return m+1;

}}

access_flags中一共有16个标志位可以使用,当前只定义了其中8个[1],没有使用到的标志位要求一律为0。以代码清单6-1中的代码为例,TestClass是一个普通Java类,不是接口、枚举或者注解,被public关键字修饰但没有被声明为final和abstract,并且它使用了JDK

1.2之后的编译器进行编译,因此它ACC_PUBLIC、ACC_SUPER标志应当为真,而

ACC_FINAL、ACC_INTERFACE、ACC_ABSTRACT、ACC_SYNTHETIC、 ACC_ANNOTATION、ACC_ENUM这6个标志应当为假,因此它的access_flags的值应为:0x0001|0x0020=0x0021。从图6-5中可以看出,access_flags标志(偏移地址: 0x000000EF)的确为0x0021。

  1. 访问标志、类索引、父类索引、接口索引集合 在class文件中的位置

好,让我们来一一击破它们,看看它们到底是什么东西。

  1. 访问标志(access_flags)能够表示什么?

访问标志(access_flags)紧接着常量池后,占有两个字节,总共16位,如下图所示:

当JVM在编译某个类或者接口的源代码时,JVM会解析出这个类或者接口的访问标志信息,然后,将这些标志设置到访问标志(access_flags)这16个位上。JVM会考虑如下设置如下访问表示信息: a. 我们知道,每个定义的类或者接口都会生成class文件(这里也包括内部类,在某个类中定义的静态内部类也会单独生成一个class文件)。

对于定义的类,JVM在将其编译成class文件时,会将class文件的访问标志的第11位设置为1。第11位叫做ACC_SUPER标志位;对于定义的接口,JVM在将其编译成class文件时,会将class文件的访问标志的第8位 设置为1 。第8位叫做ACC_INTERFACE标志位;

b.class文件表示的类或者接口的访问权限有public类型的和包package类型的。

如果类或者接口被声明为public类型的,那么,JVM将其编译成class文件时,会将class 文件的访问标志的第16位设置为1。第16位叫做ACC_PUBLIC标志符;

c. 类是否为抽象类型的,即我们定义的类有没有被abstract关键字修饰,即我们定义的类是否为抽象类。如果我们形如:

public abstract class MyClass{......}

定义某个类时,JVM将它编译成class文件的时候,会将class文件的访问标志的第7位设置为1。第7位叫做ACC_ABSTRACT标志位。 另外值得注意的是,对于定义的接口,JVM在编译接口的时候也会对class文件的访问标志上的ACC_ABSTRACT标志位设置为 1; d. 该类是否被声明了final类型,即表示该类不能被继承。
此时JVM会在编译class文件的过程中,会将class文件的访问标志的第12位设置为 1 。第12位叫做ACC_FINAL标志位; e.如果我们这个class文件不是JVM通过java源代码文件编译而成的,而是用户自己通过 class文件的组织规则生成的,那么,一般会对class文件的访问标志第4位设置为 1 。通过

JVM编译源代码产生的class文件此标志位为 0,第4位叫做ACC_SYNTHETIC标志位;

  1. 枚举类,对于定义的枚举类如:public enum EnumTest{....},JVM也会对此枚举类编译成class文件,这时,对于这样的class文件,JVM会对访问标志第2位设置为 1 ,以表示它是枚举类。第2位叫做ACC_ENUM标志位;
  2. 注解类,对于定义的注解类如:public @interface{.....},JVM会对此注解类编译成class 文件,对于这样的class文件,JVM会将访问标志第3位设置为1,以表示这是个注解类,第

3位叫做ACC_ANNOTATION标志位。

当JVM确定了上述标志位的值后,就可以确定访问标志(access_flags)的值了。实际上 JVM上述标志会根据上述确定的标志位的值,对这些标志位的值取或,便得到了访问标志

(access_flags)。如下图所示:

举例:定义一个最简单的类Simple.java,使用编译器编译成class文件,然后观察class文件中的访问标志的值,以及使用javap -v Simple 查看访问标志。

  1. package com.louis.jvm;
  2. publicclassSimple{
  1. }

使用UltraEdit查看编译成的class文件,如下图所示:

上述的图中黄色部分表示的是常量池部分,具体为什么是常量池部分不是本文的重点,有兴趣的读者可以参考我的《Java虚拟机原理图解》系列关于常量池的博客,你就可以很轻松地识别常量它们了。

常量池后面紧跟着就是访问标志,它的十六进制值为0x0021,二进制的值为:00000000 00100001,由二进制的1的位数可以得出第11、16位为1,分别对应ACC_SUPER标志位和ACC_PUBLIC标志位。

也可以通过一下运算:

0x0021 = 0x0001 | 0x0020, 即: 访问标志表示的标志是ACC_PUBLIC +

ACC_SUPER

为了验证我们的运算,使用javap -v Simple查看反编译信息如下:(小技巧:使用javap -v Simple指令的结果展示在命令提示符下显示不友好,一般我是使用javap -v Simple > temp.txt,将结果重定向到文件中,然后查看文件)

原文地址:https://www.cnblogs.com/qingruihappy/p/9691420.html

时间: 2024-11-09 04:10:32

Jvm(36),class文件结构----访问标志的相关文章

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

JVM(6)访问标志,类索引 上一篇博客讲[JVM虚拟机](5)---深入理解JVM-Class中常量池 我们知道一个class文件正常可以分为7个部分: 魔数与class文件版本 常量池 访问标志 类索引.父类索引.接口索引 字段表集合 方法表集合 属性表集合 那么这篇博客主要讲有关 访问标志 和 类索引.父类索引.接口索引 相关的理解和代码示例. 先通俗的说下这两个的作用: 访问标志: 告知该类是一个什么类型的类,是普通类?还是接口?还是枚举?或者其它类,是用什么修饰符修饰该类的. 类索引.

深入理解JVM(七)——Class文件结构

什么是JVM的"无关性"? Java具有平台无关性,也就是任何操作系统都能运行Java代码.之所以能实现这一点,是因为Java运行在虚拟机之上,不同的操作系统都拥有各自的Java虚拟机,因此Java能实现"一次编写,处处运行". 而JVM不仅具有平台无关性,还具有语言无关性. 平台无关性是指不同操作系统都有各自的JVM,而语言无关性是指Java虚拟机能运行除Java以外的代码! 这听起来非常惊人,但JVM对能运行的语言是有严格要求的.首先来了解下Java代码的运行过

JVM 之 Class文件结构

JVM 之 Class文件结构 本文写作目的: 1)为了加深自己学习的理解,2)帮助正在学习研究JVM的同仁,3)与任何热爱技术的达人交流经验,提升自己 以此为本,文章会尽量写的简洁,尽量保证理解的正确性,如有任何理解不到位或错误的地方,希望朋友们及时指出,严厉拍砖. 开始之前我们需要先了解一些基本的概念,这些概念是学习整个JVM原理的基础. 1)JVM虚拟机规范主要规范了Class文件结构,虚拟机内存结构,虚拟机加载,解析,执行Class文件的行为方式,以及一系列的字节码指令集. 2)Clas

《Java虚拟机原理图解》1.3、class文件中的访问标志、类索引、父类索引、接口索引集合

讲完了class文件中的常量池,我们就相当于克服了class文件中最麻烦的模块了.现在,我们来看一下class文件中紧接着常量池后面的几个东西:访问标志.类索引.父类索引.接口索引集合. 1. 访问标志.类索引.父类索引.接口索引集合 在class文件中的位置 好,让我们来一一击破它们,看看它们到底是什么东西. 2. 访问标志(access_flags)能够表示什么? 访问标志(access_flags)紧接着常量池后,占有两个字节,总共16位,如下图所示: 当JVM在编译某个类或者接口的源代码

JVM之Class文件结构

每一个class文件对应一个类或者接口,但是一个类或者接口不一定生成class文件,classloader直接生成. 8为字节为基础的二进制流,各个数据项按照严格的顺序排列在class文件中,没有任何分隔符,当遇到需要占用8位字节以上的数据项时,则会按照高位在前(或低位在前)方式分割为若干个8位字节存储.Big-Endian Little-Endian. 类似C语言结构体的微结构来存储数据,只包含无符号数和表两种结构. 无符号数:u1,u2,u3,u4代表响应字节大小的无符号数,用来描述数字,索

JVM初探之类文件结构

java 的 .class 文件字节码如图:Class 文件是一组以8字节为基础单位的二进制流,各个数据项目有着严格的结构.下面我们介绍下class文件的结构. 魔数 class文件的头4个字节是魔数:  ,他的作用便是验证这个文件是否是一个java虚拟机可以使用的文件, 版本号 接下来的是两个字节的小版本号,和两个字节的大版本号:  . 常量池结构 它分为两个部分: 第一部分是:常量池的容量:  即二进制 54 ,代表了 53 项常量,注意这里的容量计数是从 1 开始的即索引范围是 1 ~ 5

JVM小结--类文件结构

字节码是构成Java平台无关性的基石.实现语言无关性的基础是虚拟机和字节码存储格式. Java语言中的各种变量.关键字和运算符的语义最终是由多条字节码命令组成,因此字节码命令所能提供的语义描述能力肯定会比Java语言本身更强大. Class类文件的结构 Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件中,中间没有添加任何分隔符,所以整个Class文件中存储的内容基本上程序运行中必要的数据. 当遇到需要占用8位字节以上空间的数据项时,则会按照高

访问标志

class文件中用两个字节共16位代表访问标志(access flags),用于表明该类或接口被访问时能提供的一些信息: 标志名称 标志值 含义 ACC_PUBLIC 0x00 01 是否为Public类型 ACC_FINAL 0x00 10 是否被声明为final,只有类可以设置 ACC_SUPER 0x00 20 是否允许使用invokespecial字节码指令的新语义. ACC_INTERFACE 0x02 00 标志这是一个接口 ACC_ABSTRACT 0x04 00 是否为abstr

eclipse启动“Incompatible JVM” 和 .classpath 拒绝访问。

由于部分需要把jdk 1.7改为1.6,在启动luna时候报错“Incompatible JVM”,既然需要1.6那打死也不能再改回1.7,所以在eclipse目录中找到eclipse.ini,打开,修改“-Dosgi.requiredJavaVersion=1.7”  1.7改为1.6即可启动. 打开以后项目修改编译器,遇到“ .classpath( 拒绝访问.)”的问题,其实这个问题,是因为.classpath文件隐藏,在win下找到工程所在目录只需右键属性,把“隐藏”前面的钩去掉即可.