博客
关于我
用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办公自动化基础输出文件和文件夹
查看>>
python办公自动化基础搜索文件
查看>>
python知识:@classmethod和@staticmethod的异同
查看>>
python前端之css
查看>>
Python制作进度条,原来有这么多方法
查看>>
Python制作简单的学生成绩管理系统
查看>>
python制作甘特图的基本知识(附Demo)
查看>>
python制作一个简单的服务器,【Python】 做一个简单的 http 服务器
查看>>
Python到底能做什么?它的优点在哪?
查看>>
python利用pytorch库导出图像分割算子
查看>>
python利用pyshark监听网卡来抓包其中pyshark中摸索的一些可用参数
查看>>
python利用excel分析过杀漏失
查看>>
python判断汉字数目
查看>>
python判断文件是空的,如果是空的,就删除
查看>>
python判断密码是否正确_python密码判断是否符合要求的方法
查看>>
python判断字符串包含中文_Python 判断字符串是否包含中文
查看>>
python删除第一行_Python 乱码指北:一行删掉根目录
查看>>
Python删除列表元素的三种方法
查看>>
python初步学习-python数据类型-集合(set)
查看>>
python列表生成字典_Python中将字典转换为列表的方法
查看>>