《Java核心技术》 Class类文件结构

简介: 运行机制开篇源代码HelloWorld.java/** * Created by jack on 2017/3/16. * * @author jack * @date 2017/03/16 */public class ...
运行机制

开篇

源代码HelloWorld.java

/**
 * Created by jack on 2017/3/16.
 *
 * @author jack
 * @date 2017/03/16
 */
public class HelloWorld {
    public static void main(String[] args){
        System.out.println("Hello,World");
    }
}

编译成HelloWorld.class

cafe babe 0000 0031 0022 0a00 0600 1409
0015 0016 0800 170a 0018 0019 0700 1a07
001b 0100 063c 696e 6974 3e01 0003 2829
5601 0004 436f 6465 0100 0f4c 696e 654e
756d 6265 7254 6162 6c65 0100 124c 6f63
616c 5661 7269 6162 6c65 5461 626c 6501
0004 7468 6973 0100 0c4c 4865 6c6c 6f57
6f72 6c64 3b01 0004 6d61 696e 0100 1628
5b4c 6a61 7661 2f6c 616e 672f 5374 7269
6e67 3b29 5601 0004 6172 6773 0100 135b
4c6a 6176 612f 6c61 6e67 2f53 7472 696e
673b 0100 0a53 6f75 7263 6546 696c 6501
000f 4865 6c6c 6f57 6f72 6c64 2e6a 6176
610c 0007 0008 0700 1c0c 001d 001e 0100
0b48 656c 6c6f 2c57 6f72 6c64 0700 1f0c
0020 0021 0100 0a48 656c 6c6f 576f 726c
6401 0010 6a61 7661 2f6c 616e 672f 4f62
6a65 6374 0100 106a 6176 612f 6c61 6e67
2f53 7973 7465 6d01 0003 6f75 7401 0015
4c6a 6176 612f 696f 2f50 7269 6e74 5374
7265 616d 3b01 0013 6a61 7661 2f69 6f2f
5072 696e 7453 7472 6561 6d01 0007 7072
696e 746c 6e01 0015 284c 6a61 7661 2f6c
616e 672f 5374 7269 6e67 3b29 5600 2100
0500 0600 0000 0000 0200 0100 0700 0800
0100 0900 0000 2f00 0100 0100 0000 052a
b700 01b1 0000 0002 000a 0000 0006 0001
0000 0007 000b 0000 000c 0001 0000 0005
000c 000d 0000 0009 000e 000f 0001 0009
0000 0037 0002 0001 0000 0009 b200 0212
03b6 0004 b100 0000 0200 0a00 0000 0a00
0200 0000 0900 0800 0a00 0b00 0000 0c00
0100 0000 0900 1000 1100 0000 0100 1200
0000 0200 13

这就是jvm的byte code字节码。这一串“天书”,如果不看JVM虚拟机规范的人,正常的智商,是看不懂的。

想看懂这一串十六进制的字符,就要了解class文件协议。

第一行释义:

magic:魔数,0xCAFEBABE(cafe babe)
minor_version:占2字节,次版本号,0x0000
majro_version:占2字节,主版本号,0x0031,转化为十进制为49,是使用JDK1.5编译的(JDK1.5:0x0031,JDK1.6:0x0032,JDK1.7:0x0033)
高版本的JDK可以向下兼容以前版本的Class文件,但是无法运行以后版本的Class文件,即使文件格式并未发生变化
如果使用JDK1.5运行使用JDK1.6编译的Class文件,会报:

java.lang.UnsupportedClassVersionError: Bad version number in .class file  

就是由于JDK1.6编译的文件版本号超过了JDK1.5虚拟机所接受的范围

Java class文件是二进制文件。为了便于理解它,JVM提供者提供了javap,反汇编器(编译,反编译的本质,是“映射”)。

一切皆是映射(光剑)

使用javap产生的结果是Java汇编语言。在上面的例子中,下面的Java汇编代码是通过:

javap -c HelloWorld.class

进行反汇编得到的。

$ javap -c HelloWorld.class 
Compiled from "HelloWorld.java"
public class HelloWorld {
  public HelloWorld();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: ldc           #3                  // String Hello,World
       5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
       8: return
}


所以说,如果你足够牛逼,不需要使用java语言写源码,直接使用jvm指令集写jvm的汇编语言。这样,什么Scala,Java,Kotlin,Clojure这些运行在jvm上的高级编程语言,对你来说,真的就是浮云了。你也不需要纠结什么OOP,FP,Design Pattern, etc.

Class类文件结构

class文件的结构

简单讲,jvm的class文件是针对jvm的私家定制。只要运行在jvm上byte code,都需要按照class文件format来。否则jvm解析不了。自然无法执行。

官网文档: The Java Virtual Machine class file format

class文件时java虚拟机执行引擎的数据入口,也是java技术体系的基础支柱之一,了解class文件的结构对后面进一步了解虚拟机执行引擎有很重要的意义。

class文件是一组以八位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在class文件中,中间没有添加任何分隔符,这使得整个class文件中存储的内容几乎全部都是程序运行的必要数据,没有空隙存在。当需要占用8位字节以上的空间数据时,则会按照高位在前的方式分割成若干个8位字节进行存储。

ClassFile数据结构

ClassFile {  
    u4 magic;//魔数(0xCAFEBABE)  
    u2 minor_version;//次版本号  
    u2 major_version;//主版本号  
    u2 constant_pool_count;//常量池容量计数值  
    cp_info constant_pool[constant_pool_count-1];//常量池  
    u2 access_flags;//访问标志  
    u2 this_class;//类索引  
    u2 super_class;//父类索引  
    u2 interfaces_count;//接口计数器  
    u2 interfaces[interfaces_count];//接口索引集合  
    u2 fields_count;//字段计数器  
    field_info fields[fields_count];//字段表  
    u2 methods_count;//方法计数器  
    method_info methods[methods_count];//方法表  
    u2 attributes_count;//属性表计数器  
    attribute_info attributes[attributes_count];//属性表集合  
}  

Class文件中,类的全限定名、字段、方法都是使用CONSTANT_Utf8_info类型常量来描述名称,而该常量的长度由2个字节表示,所以类的全限定名、字段名、方法名的最大长度不能超过2个字节所能表示的最大整数,也就是65535.

博文参考:

http://blog.csdn.net/a19881029/article/details/16117251

相关文章
|
7天前
|
存储 安全 Java
java.util的Collections类
Collections 类位于 java.util 包下,提供了许多有用的对象和方法,来简化java中集合的创建、处理和多线程管理。掌握此类将非常有助于提升开发效率和维护代码的简洁性,同时对于程序的稳定性和安全性有大有帮助。
35 17
|
3天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
27 4
|
4天前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
11 2
|
8天前
|
存储 安全 Java
如何保证 Java 类文件的安全性?
Java类文件的安全性可以通过多种方式保障,如使用数字签名验证类文件的完整性和来源,利用安全管理器和安全策略限制类文件的权限,以及通过加密技术保护类文件在传输过程中的安全。
|
9天前
|
Java 编译器 Maven
Java“class file contains wrong class”解决
当Java程序运行时出现“class file contains wrong class”错误,通常是因为类文件与预期的类名不匹配。解决方法包括:1. 确保类名和文件名一致;2. 清理并重新编译项目;3. 检查包声明是否正确。
|
10天前
|
存储 Java API
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
22 4
|
12天前
|
Java 数据格式 索引
使用 Java 字节码工具检查类文件完整性的原理是什么
Java字节码工具通过解析和分析类文件的字节码,检查其结构和内容是否符合Java虚拟机规范,确保类文件的完整性和合法性,防止恶意代码或损坏的类文件影响程序运行。
|
12天前
|
Java API Maven
如何使用 Java 字节码工具检查类文件的完整性
本文介绍如何利用Java字节码工具来检测类文件的完整性和有效性,确保类文件未被篡改或损坏,适用于开发和维护阶段的代码质量控制。
|
12天前
|
存储 Java 编译器
java wrapper是什么类
【10月更文挑战第16天】
20 3
|
15天前
|
Java 程序员 测试技术
Java|让 JUnit4 测试类自动注入 logger 和被测 Service
本文介绍如何通过自定义 IDEA 的 JUnit4 Test Class 模板,实现生成测试类时自动注入 logger 和被测 Service。
20 5