初始class文件

初识class文件

​ 我们都知道Java是一门比较容易上手的语言,它有着**Write once, run anywhere的特性,那么这个特性你知道是怎么实现的吗?它和C#类似,都有一个VM(virtual machine)存在,当我们执行代码的时候,它并不是直接去执行的,而是生成中间语言,然后这个中间语言在VM中解释执行,然后虚拟机在运行期将这段代码翻译成与平台相应的机器指令再去执行。在Java中,它的中间语言就是字节码,而字节码的文件就是我们常说的.class文件

​ 简单地说就是我们的**.java文件通过javac编译成.class文件**,再将.class文件开始执行类加载流程将class文件塞到VM中,然后生成相应的二进制的机器码交给本地的操作系统去运行。

我们可以用刚接触一门语言必须敲的一段代码来演示。

coding

下面这部分我们在vim中编写的Test.java文件

//Test.java
public class Test {
    public static void main(String[] args) {
        System.out.println("hello world");
    }
}

这是我们javac之后用文本打开的class文件(因为太长只截了一部分)

//Test.class
cafe babe 0000 0034 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
Megic Number 魔数

​ 在文件中的前8位16进制数就是这个文件的格式,也就是我们常说的魔数。每个文件格式都有自己的魔数,在class文件中,它就是0xCAFEBABE。JVM加载class文件的时候,它首先去判断这个文件的魔数,如果魔数不是0xCAFEBABE的时候,直接扔出错误,终止运行。如果想要对魔数有更多的了解可以去点击这个链接Magic number

​ class文件中还有很多东西,如果你想直观的去观察的话就需要对class文件进行反编译,这里就需要用到一个指令就是javap ,具体的使用可以去自行百度。因为这个只是一个初始章节,所以我们只是在这里简单的将一些基础知识,具体的会在后面章节中写出来。

Version 版本号

​ 它由两部分组成。MajorVersion与MinorVersion这两部分构成,分别代表着主版本号和次版本号。主版本号代表着当前Java平台发布的主版本,当你使用javap -verbose xxxx.class,你会发现有一个MajorVersion和MinorVersion,因为我的JDK版本是1.8,MajorVersion就是52。JDK的版本是向下兼容的,也就是说1.8的JDK可以兼容1.7、1.6一直向下兼容。但是1.7想要去运行1.8版本编译出来的class文件是不允许的。

Constant_poll 常量池

​ 它是在魔数和版本号之后的地方,也就是class文件的第三部分。他记录了这个类中的所有的成员变量、成员方法、静态变量、静态方法和构造方法等信息。在常量池信息中,首先是constant_poll_count,代表着常量池中有多少个常量,最高为(2^16)-1个常量。接下来就是二进制描述的constant_poll_count-1个常量,里面放着字面常量符号引用字面常量就是文本字符串和被声明为final的常量,而符号引用则是类和接口的全局限定名、字段的名称和描述符、方法的名称和描述符。这样就可以在类加载的时候,在链接中的解析阶段将符号引用转化为实际引用。这些字面常量主要就是String还有一些基本数据类型,

Access_flag 类的访问权限与属性

​ 也就是我们常说的public protected private 还有默认的default这些权限以及final、abstract、super、interface等一些类的属性。

This_class 当前类

​ 保存的是这个类的全局限定名,还有在常量池中的索引。我们可以用这个索引在常量池中找到 CONSTANT_Class_info。

Super_class父类

​ 和This_class类似,不过只是把当前类改成父类

Interfaces接口列表

​ 它保存的当前类的接口列表。主要由两部分构成,interfaces_count和interfaces[]。这个数组它里面包含着interfaces_count个接口的全局限定名和一些接口信息

Fields字段列表

​ 这里面是当前类的成员列表,也就是说当前类的属性。主要由两部分构成,一个是fields_count,一个是fields[],这个和上面的Interface特别类似,fields_count表示的是当前类的变量和实例变量的总和。而fileds[],则表示字段的详细信息的数组。

Methods方法列表

​ 它保存的是当前类的方法列表,其中可以分为两个部分methods_count和methods[].methods表示的是这个类或者接口显示定义的方法,而methods[]是方法的详细信息的数组。

Attribute 属性表

​ 属性表使用两个字节表示属性的个数 attributes_count,接下来是若干个属性项的集合,可以看做是一个数组,数组的每一项都是一个属性项 attribute_info,数组的大小为 attributes_count。


参考资料:

​ 掘金小册 《JVM 字节码从入门到精通》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在线修改class文件即在程序运行时对class文件进行修改,并将修改后的结果应用到程序中。这种操作在某些特定情况下非常有用,例如需要对某个类的行为进行调试或者进行功能测试时,可以通过在线修改class文件来实现快速验证功能的效果和正确性。 在线修改class文件的方法有多种,其中比较常见的一种是使用Java Agent机制来完成。Java Agent是一种Java平台提供的机制,它可以在程序启动时对程序的字节码进行转换和增强,并在程序运行时对应用的行为进行动态的修改。使用Java Agent来进行在线修改class文件时,可以借助bytecode engineering工具,对class文件进行访问和修改,从而实现一些高级、复杂的功能。 除此之外,还有一些第三方工具也可以用来进行在线修改class文件,例如Bytecode Viewer、ASM等。这些工具提供了丰富的API和插件,可以方便地进行class文件的编辑、修改和调试。使用这些工具可以快速对Java类进行修改,同时还可以对代码进行实时调试和测试,提高编码效率。 需要注意的是,在线修改class文件可能会涉及到一些安全问题,因此需要谨慎操作,避免对程序的稳定性和可靠性产生不良影响。此外,需要确保修改后的class文件与原始的class文件兼容,并且在不修改代码的情况下,保持程序的正常运行。 ### 回答2: 在线修改class文件是指在程序运行时动态地修改已经编译好的Java类文件。这种技术可以用来进行调试或者对程序进行动态修改。 在Java中,可以使用一些工具来实现在线修改class文件。比较常用的有两种方式: 一种是使用Java自带的Instrumentation API,在程序启动时进行初始化,并且在运行时对类进行修改,这样可以拦截类的加载,从而对类进行修改。 另一种方式则是使用第三方工具,比如JRebel。JRebel可以在应用运行时自动加载和应用class文件的更改,从而增加了开发者的生产力,减少了项目开发周期。 无论使用哪种方式,都需要注意在线修改class文件会对程序的稳定性造成一定的影响,如果不谨慎使用可能会导致应用程序崩溃或者出现其他问题。因此,在进行这种操作时,一定要仔细测试,并且在生产环境中谨慎使用。 ### 回答3: 在Java中,class文件编译后的Java代码,它是Java程序在计算机上运行的最终形式。在线修改class文件指的是在程序运行时,修改class文件中的一些内容而不需要重新编译整个程序。 在线修改class文件通常是用于调试和测试目的。它可以允许开发者实时修改程序的行为,并且可以减少调试时间,提高程序开发效率。 为了实现在线修改class文件,我们可以使用一些工具,比如Java Agent和字节码操作框架ASM。Java Agent是一个Java应用程序,在程序运行时可以修改类加载器的行为,从而实现对class文件的动态修改。字节码操作框架ASM则提供了直接修改class文件字节码的能力。 需要注意的是,虽然在线修改class文件可以提高程序开发效率,但在生产环境中不建议使用。因为这样做可能会导致程序运行出现意想不到的错误,甚至影响程序安全性。最好还是在开发调试阶段进行在线修改,将修改后的代码重新编译并部署到生产环境。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值