一、概述
class文件全名称为 Java class
文件,主要在平台无关性和网络移动性方面使 Java
更适合网络。该文件打破了 C
或者 C++
等语言所遵循的传统,使用这些传统语言写的程序通常首先被编译,然后被连接成单独的、专门支持特定硬件平台和操作系统的二进制文件。
通常情况下,一个平台上的二进制可执行文件不能在其他平台上工作。而 class
文件是可以运行在任何支持 Java虚拟机
的硬件平台和操作系统上的二进制文件。
一个典型 Java 程序产生的过程:
当我们对一个 Java 源程序进行 javac
编译后就会生成 class
文件。
就以 HelloWorld.java
源程序为例:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello World ~~");
}
}
使用 javac
编译
在 Java 中,JVM 可以理解的代码叫作字节码
,也就是 .class
文件,它不面向任何特定的处理器,只面向虚拟机
。Java 语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,并且保留了解释型语言可移植的特点,而通过即时编译器(JIT)
又有编译型语言执行效率高的特点。所以 Java 程序运行时比较高效,同时 Java 通过字节码文件和虚拟机之间的关系,实现了平台无关性,一次编译,各平台都可运行。
值得一提的是,不仅是 Java 源程序可以被编译成 .class
文件,有些语言也可以编译成 .class
文件,而且都可以运行在 JVM 上。
所以说 JVM
和语言无关,只要符合 .class
文件的规范,都可以运行。
二、打开 Class 文件
- 方式一:使用文本编辑器打开
我们可以使用一些 文本编辑器
来打开 .class
文件,比如 Nodpad++
可以看到打开之后显示的内容是一些夹杂着字符的乱码,其实文件中包含的是一些字节序列,但有些字节不能显示为一个字符,所以看起来就是乱码。
我们可以在 Nodpad++
上下载 HEX-Editor
的插件,就能看到该文件的十六进
制内容了(使用Nodepad++工具查看文件的十六进制)
- 方式二:编写代码读取
class
文件的内容并显示
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Scanner;
public class ReadDis {
public static void main(String[] args) throws IOException {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入当前目录下要显示的文件名:");
String fileName = scanner.next();
FileInputStream inputStream = new FileInputStream(fileName);
byte[] data = new byte[inputStream.available()];
int read = inputStream.read(data);
inputStream.close();
System.out.println("文件内容:");
showASCII(data);
showHex(data);
}
// 显示为ASCII格式
public static void showASCII(byte[] data) throws UnsupportedEncodingException {
System.out.println("\r\n\t文件的ASCII内容");
String ascData = new String(data, "ASCII");
for (int i = 0; i < ascData.length(); i+=40) {
int t = i+40;
if (t>ascData.length()) {
t=ascData.length();
}
String len = ascData.substring(i,t);
System.out.print(len);
}
}
// 显示为十六进制格式
public static void showHex(byte[] data) {
System.out.println("\r\n\t文件的十六进制内容");
for (int i = 0; i < data.length; i++) {
String hex = Integer.toHexString(data[i] & 0xFF);
if (hex.length() < 2) {
hex = "0" + hex;
}
System.out.print(hex + "");
if ((i+1)%16==0) {
System.out.println();
}
}
}
}
- 方式三:在命令行执行
javap -c -s -p HelloWorld.class
命令
javap
是 JDK 自带的反编译工具,是给 JVM 看的代码。
- 方式四:使用反编译工具
可以使用一些反编译工具,比如:Q-dir
,或者是开发工具,比如:IDEA
等打开 .class
,打开之后看到的为反编译内容。
三、class 文件内容
在官网中有明确的说明文档:https://docs.oracle.com/javase/specs/index.html
不过是英文的,或者借鉴博客:详解.class文件