1.产生

源码(.java文件)——>编译器(如:javac)——>字节码(.class文件)——>虚拟机(如:HotSpot)执行

2.Class文件

 1)构成:

                    魔数、版本号、常量池、访问标志、索引、字段表集合、方法表集合、Signature属性表、SourseFile属性表

 2)例子:

[1] .java文件

桌面/test/test/Father.java、桌面/test/test/Father_interface.java、桌面/test/Son.java  ;

[2]编译出.class文件

cd  桌面/test;

桌面/test>javac  Son.java;

[3]查看.class文件

桌面/test>javap -verbose  Son;

Classfile /C:/Users/Administrator/Desktop/test/Son.class
  Last modified 2016-4-11; size 1005 bytes
  MD5 checksum 7d138d76267a6bb372eba05296e2c932魔数
  Compiled from "Son.java"
接口索引,指向常量池
  SourceFile: "Son.java" 源码属性表<源码名称,指向常量池>
  minor version: 0
  major version: 51主板本号
  flags: ACC_PUBLIC, ACC_SUPER访问标志<当前类>
Constant pool:常量池  一、符号引用{
   #1 = Methodref          #16.#33        //  test/Father."<init>":()V
   #2 = Fieldref           #15.#34        //  test/Son.sId_literal:I                 《字段》符号引用
   #3 = Fieldref           #35.#36        //  java/lang/System.out:Ljava/io/PrintStream;
   #4 = Class              #37            //  java/lang/StringBuilder                类/接口》符号引用
   #5 = Methodref          #4.#33         //  java/lang/StringBuilder."<init>":()V   《类方法》符号引
   #6 = String             #38            //  statical_sId =                          《字面量——静态字段》符号引用
   #7 = Methodref          #4.#39         //  java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/Strin
gBuilder;
   #8 = Fieldref           #15.#40        //  test/Son.statical_sId:I
   #9 = Methodref          #4.#41         //  java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
  #10 = Methodref          #4.#42         //  java/lang/StringBuilder.toString:()Ljava/lang/String;
  #11 = Methodref          #43.#44        //  java/io/PrintStream.println:(Ljava/lang/String;)V
  #12 = String             #45            //  Son实例构造器!                           《字面量——System.out的字符串》符号引用
  #13 = String             #46            //  hello!this is son!
  #14 = String             #47            //  Son类构造器<clinit>执行!
  #15 = Class              #48
  #16 = Class              #49
  #17 = Class              #50            //  test/Father_interface 3    }

  二、常量类型{                         
  #18 = Utf8               final_sId    UTF-8编码的字符串
  #19 = Utf8               I
  #20 = Utf8               ConstantValue
  #21 = Integer                      整型字面量
  #22 = Utf8               statical_sId
  #23 = Utf8               sId_literal
  #24 = Utf8               sId_nonLiteral
  #25 = Utf8               <init>
  #26 = Utf8               ()V   /**返回类型*/
  #27 = Utf8               Code
  #28 = Utf8               LineNumberTable
  #29 = Utf8               sayHello
  #30 = Utf8               <clinit>
  #31 = Utf8               SourceFile
  #32 = Utf8               Son.java       

    }  三、符号引用、数据{
  #33 = NameAndType        #25:#26        //  "<init>":()V   《字段/方法部分》符号引用
  #34 = NameAndType        #23:#19        //  sId_literal:I
  #35 = Class              #51            //  java/lang/System
  #36 = NameAndType        #52:#53        //  out:Ljava/io/PrintStream;
  #37 = Utf8               java/lang/StringBuilder
  #38 = Utf8               statical_sId =
  #39 = NameAndType        #54:#55        //  append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #40 = NameAndType        #22:#19        //  statical_sId:I
  #41 = NameAndType        #54:#56        //  append:(I)Ljava/lang/StringBuilder;
  #42 = NameAndType        #57:#58        //  toString:()Ljava/lang/String;
  #43 = Class              #59            //  java/io/PrintStream
  #44 = NameAndType        #60:#61        //  println:(Ljava/lang/String;)V
  #45 = Utf8               Son实例构造器!   }符号引用
  #46 = Utf8               hello!this is son!
  #47 = Utf8               Son类构造器<clinit>执行!
  #48 = Utf8               test/Son
  #49 = Utf8               test/Father
  #50 = Utf8               test/Father_interface
  #51 = Utf8               java/lang/System
  #52 = Utf8               out
  #53 = Utf8               Ljava/io/PrintStream;
  #54 = Utf8               append
  #55 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
  #56 = Utf8               (I)Ljava/lang/StringBuilder;
  #57 = Utf8               toString
  #58 = Utf8               ()Ljava/lang/String;
  #59 = Utf8               java/io/PrintStream
  #60 = Utf8               println
  #61 = Utf8               (Ljava/lang/String;)V
{
  public test.Son();方法表——实例构造器
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method test/Father."<init>":()V
         4: aload_0
         5: bipush        123
         7: putfield      #2                  // Field sId_literal:I
        10: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
        13: new           #4                  // class java/lang/StringBuilder
        16: dup
        17: invokespecial #5                  // Method java/lang/StringBuilder."<init>":()V
        20: ldc           #6                  // String statical_sId =
        22: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/
lang/StringBuilder;
        25: getstatic     #8                  // Field statical_sId:I
        28: invokevirtual #9                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilde
r;
        31: invokevirtual #10                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        34: invokevirtual #11                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        37: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
        40: ldc           #12                 // String Son实例构造器!
        42: invokevirtual #11                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        45: sipush        333
        48: putstatic     #8                  // Field statical_sId:I
        51: return
      LineNumberTable:
        line 15: 0
        line 7: 4
        line 16: 10
        line 17: 37
        line 18: 45
        line 19: 51

  public void sayHello();方法表——sayHello()
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #13                 // String hello!this is son!
         5: invokevirtual #11                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: return
      LineNumberTable:
        line 21: 0
        line 22: 8

  static {};方法表——类构造器(静态代码块)
    flags: ACC_STATIC
    Code:
      stack=3, locals=0, args_size=0
         0: bipush        123
         2: putstatic     #8                  // Field statical_sId:I
         5: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
         8: new           #4                  // class java/lang/StringBuilder
        11: dup
        12: invokespecial #5                  // Method java/lang/StringBuilder."<init>":()V
        15: ldc           #6                  // String statical_sId =
        17: invokevirtual #7                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/
lang/StringBuilder;
        20: getstatic     #8                  // Field statical_sId:I
        23: invokevirtual #9                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilde
r;
        26: invokevirtual #10                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        29: invokevirtual #11                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        32: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
        35: ldc           #14                 // String Son类构造器<clinit>执行!
        37: invokevirtual #11                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        40: return
      LineNumberTable:
        line 6: 0
        line 11: 5
        line 12: 32
        line 13: 40
}

3.分析

魔数 版本号 常量池   访问标志 索引 字段表集合                                                                           

因为后缀名是可以改的,所以

用它来确定真的是.class文件

44=JDK1.0

45=jdk1.1

....

字面量

基本类型数据值      

<int、double等>

符号引用

<指向UTF-8字符串>

记录类信息

访问标志

全限定名

记录方

简单名称

返回类型

参数列表 

记录成员属性

简单名称

访问标志

返回类型

 

本类索引

继承父类索引

实现接口索引

<指向”常量池“符号引用, 记录类信息>

每张表:           

        访问标志      

 //指向常量池-符号引用-成员

     名称

        描述            返回类型

//指向常量池-符号引用-成员

        附加属性表

————ConstantValue表

静态成员才有此属性表,如果被final修饰,就直接把取值(常量池-字面量)写到表中

————Signature表    

                        //记录泛型信息

方法表集合

     Signature表

SourseFile属性表

每张表:

访问标志

 //指向常量池-符号引用-方法

名称

描述

返回类型、参数列表

//指向常量池-符号引 用-方法

附加属性表

————Code表

 虚拟机字节码指令     (方法内容,抽象方  法无此属性表) 

————Linumber表

————局部变量表

————异常表

————Signature表

记录泛型信息

  

       记录本类泛型信息

表1

    <本类>

     对应源码文件名称索引                  

表2:

    <内部类>

    对应源码文件名称索引

....

4.相关术语

1)特征签名

-方法表中所有“参数-描述”的集合,指向常量池的符号引用

2)元数据

-方法、字段、类和包的描述信息(即字节码中非虚拟机字节码指令部分)

3)<client>()方法

·定义:

-即“类构造器”,是由编译器自动收集类中类变量的赋值和静态语句块中语句合并产生,在编译过程中,由编译器将该方法的bit流写入.Class文件。

·例子:

-收集“类变量的赋值”

Person.java文件:static int i =20;——————>Person.Class文件: static Person{ int i =20;}

-收集“静态语句块中语句”

Person.java文件:static {Person.i =50;}——————>Person.Class文件: static Person{ int i =20; i =50;}

·性质:

-按在.java源文件中出现的顺序,依次进行收集;

-“类构造器”并不是必须被产生的,因为一个类或接口可以没有静态语句块和类变量的赋值操作;

-接口也中可以有“类构造器”,因为从语法上,虽然接口中不能含static{}静态代码块,但是可以含“类变量的赋值”;

读《深入理解Java虚拟机》有感——第一部分:Class文件的结构的更多相关文章

  1. 【深入理解JAVA虚拟机】第一部分.走进Java

    Java技术体系 如果仅从传统意义上来看,Sun官方所定义的Java技术体系包括以下几个组成部分:Java程序设计语言各种硬件平台上的Java虚拟机Class文件格式Java API类库来自商业机构和 ...

  2. 深入理解Java虚拟机(第2版) 笔记目录

    本篇为读深入理解Java虚拟机(第2版)一书的笔记目录. Java 运行期数据区 Java 垃圾回收算法 Java 内存分配策略 Java 类文件结构 Java 加载.链接.初始化 Java 类加载器

  3. 读《深入理解Java虚拟机》

    Java虚拟机运行时数据区 对象的创建 Java创建对象,在语言层面上使用new关键字.虚拟机遇到new关键字时,会检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的 ...

  4. 深入理解Java虚拟机--下

    深入理解Java虚拟机--下 参考:https://www.zybuluo.com/jewes/note/57352 第10章 早期(编译期)优化 10.1 概述 Java语言的"编译期&q ...

  5. 《深入理解Java虚拟机》-----第6章 类文件结构——Java高级开发必须懂的

    代码编译的结果从本地机器码转变为字节码,是存储格式发展的一小步,却是编程语言发展的一大步. 6.1 概述 记得在第一节计算机程序课上我的老师就讲过:“计算机只认识0和1,所以我们写的程序需要经编译器翻 ...

  6. 深入理解Java虚拟机(类文件结构+类加载机制+字节码执行引擎)

    目录 1.类文件结构 1.1 Class类文件结构 1.2 魔数与Class文件的版本 1.3 常量池 1.4 访问标志 1.5 类索引.父索引与接口索引集合 1.6 字段表集合 1.7 方法集合 1 ...

  7. jvm--深入理解java虚拟机 精华总结(面试)(转)

    深入理解java虚拟机 精华总结(面试)(转) 原文地址:http://www.cnblogs.com/prayers/p/5515245.html 一.运行时数据区域 3 1.1 程序计数器 3 1 ...

  8. 2018.4.23 深入理解java虚拟机(转)

    深入理解java虚拟机 精华总结(面试) 一.运行时数据区域 Java虚拟机管理的内存包括几个运行时数据内存:方法区.虚拟机栈.本地方法栈.堆.程序计数器,其中方法区和堆是由线程共享的数据区,其他几个 ...

  9. 《深入理解Java虚拟机》学习笔记

    <深入理解Java虚拟机>学习笔记 一.走近Java JDK(Java Development Kit):包含Java程序设计语言,Java虚拟机,JavaAPI,是用于支持 Java 程 ...

随机推荐

  1. u-boot中nandflash初始化流程分析(转)

    u-boot中nandflash初始化流程分析(转) 原文地址http://zhuairlunjj.blog.163.com/blog/static/80050945201092011249136/ ...

  2. Java中检测字符串的编码格式

    public static String getEncoding(String str) { String encode = "GB2312"; try { if (str.equ ...

  3. 【洛谷 p3374】模板-树状数组 1(数据结构)

    题目:已知一个数列,你需要进行下面两种操作:1.将某一个数加上x:2.求出某区间每一个数的和. 解法:树状数组求前缀和. #include<cstdio> #include<cstd ...

  4. SharpGL学习笔记(十九) 摄像机漫游

    所谓的摄像机漫游,就是可以在场景中来回走动. 现实中,我们通过眼睛观察东西,身体移动带动眼睛移动观察身边的事物,这也是在漫游. 在OpenGL中我们使用函数LookAt()来操作摄像机在三维场景中进行 ...

  5. [Tool] Windows 8.1安装SQL Server

    [Tool] Windows 8.1安装SQL Server 问题情景 因为工作的关系,需要在Windows 8.1.64Bit设备上安装SQL Server 2012.本来以为是个只要按下一步就可以 ...

  6. 【.net程序破解】实战之标志位破解绕过注册法

    今天有时间玩了下一个不错的软件Advanced System Cleaner,可惜要注册 于是想办法给破解了,这是跟之前不同的地方,属于.NET破解教程: 软件地址 - http://www.crsk ...

  7. Android开发 Failed to install *.apk on device 'emulator-5554': EOF

    在运行android 程序时出现这样的错误: Failed to install homework.apk on device 'emulator-5554': EOF java.io.IOExcep ...

  8. Oracle自动统计信息的收集原理及实验

    [日期:2014-11-21]来源:Linux社区  作者:stevendbaguo[字体:大 中 小] 从Oracle Database 10g开始,Oracle在建库后就默认创建了一个名为GATH ...

  9. Step by step configuration of Outgoing Emails from SharePoint to Microsoft Online

    First of all your SharePoint server should be added to Microsoft online safe sender list, so that Sh ...

  10. [Android]编译错误:Could not get unknown property 'release' for SigningConfig container

    使用Gradle进行安卓编译时,出现如下错误: Could not get unknown property 'release' for SigningConfig container. 原因: 在主 ...