博客
关于我
用Java实现JVM第二章《搜索class文件》
阅读量:614 次
发布时间:2019-03-13

本文共 5830 字,大约阅读时间需要 19 分钟。

Java虚拟机如何寻找并读取class文件

本章节将介绍Java虚拟机如何从指定路径寻找并读取Java类文件的字节码。

环境配置

为了完成本例案例,建议使用以下环境:

  • JDK版本:Java Development Kit 1.8.0
  • IDE:IntelliJ IDEA Community Edition 2018.3.1 x64
  • 编辑器:Notepad++,并预先安装HEX-Editor插件用于查看class文件的字节码

项目结构

项目文件结构如下:

itstack-demo-jvm-02├── pom.xml└── src    ├── main    │    └── java    │         └── org.itstack.demo.jvm    │              ├── classpath    │              │   ├── impl    │              │   │   ├── CompositeEntry.java    │              │   │   ├── DirEntry.java    │              │   │   ├── WildcardEntry.java    │              │   │   └── ZipEntry.java    │              │   ├── Classpath.java    │              │   └── Entry.java    │              ├── Cmd.java    │              └── Main.java    └── test        └── java            └── org.itstack.demo.test                └── HelloWorld.java

代码解析

1. HelloWorld.java

package org.itstack.demo.test;import org.itstack.demo.jvm.classpath.Classpath;import java.util.Arrays;public class HelloWorld {    public static void main(String[] args) {        // 请根据实际需要添加相应的参数        Cmd cmd = Cmd.parse(args);        // 进行JVM启动和类加载等操作    }}

2. Classpath.java

package org.itstack.demo.jvm.classpath;import org.itstack.demo.jvm.classpath.impl.WildcardEntry;import java.io.File;import java.nio.file.Files;import java.nio.file.Paths;public class Classpath {    private Entry bootstrapClasspath;    private Entry extensionClasspath;    private Entry userClasspath;    public Classpath(String jreOption, String cpOption) {        bootstrapAndExtensionClasspath(jreOption);        parseUserClasspath(cpOption);    }    private void bootstrapAndExtensionClasspath(String jreOption) {        String jreDir = getJreDir(jreOption);        // 加载JRE的bootstrap和extension类路径        bootstrapClasspath = new WildcardEntry(jreDir + File.separator + "lib" + File.separator + "*");        extensionClasspath = new WildcardEntry(jreDir + File.separator + "lib" + File.separator + "ext" + File.separator + "*");    }    private String getJreDir(String jreOption) {        if (jreOption != null && Files.exists(Paths.get(jreOption))) {            return jreOption;        }        if (Files.exists(Paths.get("./jre"))) {            return "./jre";        }        String jh = System.getenv("JAVA_HOME");        if (jh != null) {            return Paths.get(jh, "jre").toString();        }        throw new RuntimeException("无法找到JRE目录");    }    private void parseUserClasspath(String cpOption) {        if (cpOption == null) {            cpOption = ".";        }        userClasspath = Entry.create(cpOption);    }    public byte[] readClass(String className) throws Exception {        className = className + ".class";        try {            return bootstrapClasspath.readClass(className);        } catch (Exception e) {            // 忽略        }        try {            return extensionClasspath.readClass(className);        } catch (Exception e) {            // 忽略        }        return userClasspath.readClass(className);    }}

3. Entry.java

package org.itstack.demo.jvm.classpath;import org.itstack.demo.jvm.classpath.impl.CompositeEntry;import org.itstack.demo.jvm.classpath.impl.DirEntry;import org.itstack.demo.jvm.classpath.impl.WildcardEntry;import org.itstack.demo.jvm.classpath.impl.ZipEntry;import java.io.File;import java.io.IOException;public interface Entry {    byte[] readClass(String className) throws IOException;    static Entry create(String path) {        if (path.contains(File.pathSeparator)) {            return new CompositeEntry(path);        }        if (path.endsWith("*")) {            return new WildcardEntry(path);        }        if (path.endsWith(".jar") || path.endsWith(".JAR") || path.endsWith(".zip") || path.endsWith(".ZIP")) {            return new ZipEntry(path);        }        return new DirEntry(path);    }}

测试结果

通过运行Main.java可以看到以下输出结果:

classpath:org.itstack.demo.jvm.classpath.Classpath@4bf558aaclass:E:\itstack\git\istack-demo\itstack-demo-jvm\itstack-demo-jvm-02\target\test-classes\org\itstack\demo\test\HelloWorldargs:nullclassData:ca fe ba be 00 00 00 34 00 22 0a 00 06 00 14 09 00 15 00 16 08 00 17 0a 00 18 00 19 07 00 1b 01 00 06 3c 69 6e 69 74 3e 01 00 03 28 29 56 01 00 04 43 6f 64 65 01 00 0f 4c 69 6e 65 4e 75 6d 62 65 72 54 61 62 6c 65 01 00 12 4c 6f 63 61 6c 56 61 72 69 61 62 6c 65 54 61 62 6c 65 01 00 04 74 68 69 73 01 00 22 4c 6f 72 67 2f 69 74 73 74 61 63 6b 2f 64 65 6d 6f 2f 74 65 73 74 2f 48 65 6c 6c 6f 57 6f 72 6c 64 3b 01 00 04 6d 61 69 6e 01 00 16 28 5b 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 01 00 04 61 72 67 73 01 00 13 5B 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 01 00 0F 48 65 6C 6C 6F 57 6F 72 6C 64 2E 6A 61 76 61 0C 00 07 00 08 07 00 1C 0C 00 1D 00 1E 01 00 0D 48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21 07 00 1F 0C 00 20 00 21 01 00 20 6F 72 67 2F 69 74 73 74 61 63 6B 2F 64 65 6D 6F 2F 74 65 73 74 2F 48 65 6C 6C 6F 57 6F 72 6C 64 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 53 79 73 74 65 6D 01 00 03 6F 75 74 01 00 15 4C 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 3B 01 00 13 6A 61 76 61 2F 69 6F 2F 50 72 69 6E 74 53 74 72 65 61 6D 01 00 07 70 72 69 6E 74 6C 6E 01 00 15 28 4C 6A 61 76 61 2F 6C 61 6E 67 2F 53 74 72 69 6E 67 3B 29 56 00 21 00 05 00 06 00 00 00 00 00 02 00 01 00 07 00 08 00 01 00 09 00 00 00 2F 00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 0A 00 00 00 06 00 01 00 00 00 03 00 0B 00 00 00 0C 00 01 00 00 00 05 00 0C 00 0D 00 00 00 09 00 0E 00 0F 00 01 00 09 00 00 00 37 00 02 00 01 00 00 00 09 B2 00 02 12 03 B6 00 04 B1 00 00 00 02 00 0A 00 00 00 0A 00 02 00 00 00 06 00 08 00 07 00 0B 00 00 00 0C 00 01 00 00 00 09 00 10 00 11 00 00 00 01 00 12 00 00 00 02 00 13

通过Notepad++打开HelloWorld.class文件,并使用HEX-Editor插件查看其字节码,可以看到类的具体字节排列。

转载地址:http://ifiaz.baihongyu.com/

你可能感兴趣的文章
Python基础教程(第2版 修订版) pdf
查看>>
python基础实践(四)
查看>>
Python基础学习笔记(九)常用数据类型转换函数
查看>>
Python基础学习参考(五):字符串和编码
查看>>
Python基础学习
查看>>
python基础变量之---集合
查看>>
python基础变量之---字典
查看>>
python基础变量之---列表
查看>>
python基础变量之---元组
查看>>
python基础内容_Python基础入门必须了解的
查看>>
Python基础之面向对象2(封装)
查看>>
Python基础之给函数增加元信息
查看>>
python基础之字符编码
查看>>
python基础之多线程与多进程(二)
查看>>
Python基础之基本数据类型一《数字与字符串》
查看>>
python基础之变量---总纲
查看>>
Python基础之列表
查看>>
Python基础之Python环境搭建
查看>>
python基础之--迭代器和生成器及异常处理
查看>>
python基础之--包和模块
查看>>