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

1.产生

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

2.Class文件

 1)构成:

 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"
public class test.Son extends test.Father implements test.Father_interface索引(1类索引、2父类索引、3接口索引,指向常量池
  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实例构造器!
  #13 = String             #46            //  hello!this is son!
  #14 = String             #47            //  Son类构造器<clinit>执行!
  #15 = Class              #48            //  test/Son 1
  #16 = Class              #49            //  test/Father 2
  #17 = Class              #50            //  test/Father_interface 3    }符号引用
  #18 = Utf8               final_sId
  #19 = Utf8               I
  #20 = Utf8               ConstantValue
  #21 = Integer            123 字面量
  #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字符串)

1)记录类

访问标志+全限定名

2)记录方法

简单名称+返回类型+参数列表

3)记录成员属性

简单名称+返回类型

 
分为:本类、继承父类类、实现接口

指向“常量池—记录类”

 
每张表:

访问标志、(名称、描述【如:返回类型、参数等】)、附加属性attributes(Code属性表、Linumber属性表、局部变量表、异常表等)

/** 括号中表示是指向“常量池”*/

时间: 2025-01-05 02:36:17

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

《深入理解Java虚拟机》第一部分(Java技术体系,Java虚拟机,Java技术趋势)

第一部分 走进Java 1.Java技术体系 Sun官方定义的Java技术体系包括一下几个组成部分: Java程序设语言 各种硬件平台上的Java虚拟机 Class文件格式 Java API类库 第三方Java类库 JDK是用于支持Java程序开发的最小环境,Java程序设计语言.Java虚拟机.JavaAPI类库统称为JDKJRE是支持Java程序运行的标准环境,JavaAPI类库中的JavaSEAPI子集和Java虚拟机统称为JRE 按照Java技术关注的重点业务领域来分,Java技术体系可

《深入理解Java虚拟机》读书笔记---第一章 走进Java

一.为什么要读此书 <深入理解Java虚拟机>这本书读了很多次,每次读都会有不一样的感受.首先说一下为什么要读这本书,如果把Java比喻成乾坤大挪移,那了解虚拟机的工作原理就是练习九阳神功,java语言是招式,对虚拟机的认识是内功心法,只有内功心法强大,所使的招式才强大,这就是为什么阳顶天只能把乾坤大挪移练到第四层,而张无忌能练到第七层.由于java虚拟机的强大,把很多功能都隐藏了,例如内容管理,垃圾回收机制等,使得很多java程序猿对这一块的知识所有缺失,编码的时候也是似懂非懂的,以至于遇到

读《深入理解Java虚拟机》

Java虚拟机运行时数据区 对象的创建 Java创建对象,在语言层面上使用new关键字.虚拟机遇到new关键字时,会检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载.解析和初始化过.如果没有,那就必须先执行类加载过程.类加载通过之后,虚拟机将会为新生对象分配内存.对象所需的内存在类加载完成后就能完全确定.分配内存的方法有"指针碰撞"和"空闲列表"两种方式,如果Java堆是规整的,则采用前者:否则,采用后者.Java

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

深入理解java虚拟机 精华总结(面试)(转) 一.运行时数据区域 3 1.1 程序计数器 3 1.2 Java虚拟机栈 3 1.3 本地方法栈 3 1.4 Java堆 3 1.5 方法区 3 1.6 运行时常量池 4 二. hotspot虚拟机对象 4 2.1 对象的创建 4 检查 4 分配内存 4 Init 4 2.2 对象的内存布局 4 2.3 对象的访问定位 4 使用句柄访问 4 使用直接指针访问 5 三. OutOfMemoryError 异常 5 3.1 Java堆溢出 5 3.2

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

周志明的<深入理解Java虚拟机>很好很强大,阅读起来颇有点费劲,尤其是当你跟随作者的思路一直探究下去,开始会让你弄不清方向,难免有些你说的啥子的感觉.但知识不得不学,于是天天看,反复看,就慢慢的理解了.我其实不想说这种硬磨的方法有多好,我甚至不推荐,我建议大家阅读这本书时,由浅入深,有舍有得,先从宏观去理解去阅读,再慢慢深入,有条不紊的看下去.具体来说,当你看书的某一部分时,先看这部分的章节名,了解这部分这一章在讲什么,然后再看某一章,我拿"类文件结构"这一章来说,我必须

《深入理解Java虚拟机》:类加载的过程

<深入理解Java虚拟机>:类加载的过程 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载.验证.准备.解析.初始化.使用和卸载七个阶段.其中类加载的过程包括了加载.验证.准备.解析.初始化五个阶段. 下面详细讲述类加载过程中每个阶段所做的工作. 加载 加载时类加载过程的第一个阶段,在加载阶段,虚拟机需要完成以下三件事情: 1.通过一个类的全限定名来获取其定义的二进制字节流. 2.将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构. 3.在Java堆中生成一

【深入理解Java虚拟机】类加载机制

本文内容来源于<深入理解Java虚拟机>一书,非常推荐大家去看一下这本书. 本系列其他文章: [深入理解Java虚拟机]Java内存区域模型.对象创建过程.常见OOM [深入理解Java虚拟机]垃圾回收机制 1.类加载机制概述 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 在java中,类型的加载.连接和初始化过程都是在程序运行期间完成的,这种策略虽然会带来一些性能开销,但是却为jav

深入理解Java虚拟机到底是什么

摘自:http://blog.csdn.net/zhangjg_blog/article/details/20380971 什么是Java虚拟机 我们都知道Java程序必须在虚拟机上运行.那么虚拟机到底是什么呢?先看网上搜索到的比较靠谱的解释: 虚拟机是一种抽象化的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的.Java虚拟机有自己完善的硬体架构,如处理器.堆栈.寄存器等,还具有相应的指令系统.JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的

《深入理解java虚拟机》:类的初始化

深入理解java虚拟机>:类的初始化 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载.验证.准备.解析.初始化.使用和卸载七个阶段.其中验证.准备.解析3个部分统称为连接.类加载的过程包括了加载.验证.准备.解析.初始化五个阶段. 加载.验证.准备.初始化和卸载这5个阶段的顺序时确定的,类的加载过程必须按照这种顺序按部就班的开始,而解析阶段则不一定,它在某些情况下可以在初始化阶段之后开始,这是为了支持Java语言的运行时绑定(也成为动态绑定或晚期绑定).另外注意这里的

(1) 深入理解Java虚拟机到底是什么?

好文转载:http://blog.csdn.net/zhangjg_blog/article/details/20380971 什么是Java虚拟机 作为一个Java程序员,我们每天都在写Java代码,我们写的代码都是在一个叫做Java虚拟机的东西上执行的.但是如果要问什么是虚拟机,恐怕很多人就会模棱两可了.在本文中,我会写下我对虚拟机的理解.因为能力所限,可能有些地方描述的不够欠当.如果你有不同的理解,欢迎交流. 我们都知道Java程序必须在虚拟机上运行.那么虚拟机到底是什么呢?先看网上搜索到