案例简述
本章节主要了解Java虚拟机从哪里寻找class文件并且读取class内字节码
环境准备
- jdk 1.8.0
- IntelliJ IDEA Community Edition 2018.3.1 x64
- Notepad++ (插件安装HEX-Editor,用于查看class字节)
配置信息
- 调试配置
- 配置位置:Run/Debug Configurations -> program arguments
- 配置内容:-Xjre “C:\Program Files\Java\jdk1.8.0_161\jre” E:\itstack\git\istack-demo\itstack-demo-jvm\itstack-demo-jvm-02\target\test-classes\org\itstack\demo\test\HelloWorld
代码示例
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
pom.xml
<!-- 命令行参数解析器 -->
<dependency>
<groupId>com.beust</groupId>
<artifactId>jcommander</artifactId>
<version>1.72</version>
</dependency>
CompositeEntry.java
package org.itstack.demo.jvm.classpath.impl;
import org.itstack.demo.jvm.classpath.Entry;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* http://www.itstack.org
* create by fuzhengwei on 2019/4/24
*/
public class CompositeEntry implements Entry {
private final List<Entry> entryList = new ArrayList<>();
public CompositeEntry(String pathList) {
String[] paths = pathList.split(File.pathSeparator);
for (String path : paths) {
entryList.add(Entry.create(path));
}
}
@Override
public byte[] readClass(String className) throws IOException {
for (Entry entry : entryList) {
try {
return entry.readClass(className);
} catch (Exception ignored) {
//ignored
}
}
throw new IOException("class not found " + className);
}
@Override
public String toString() {
String[] strs = new String[entryList.size()];
for (int i = 0; i < entryList.size(); i++) {
strs[i] = entryList.get(i).toString();
}
return String.join(File.pathSeparator, strs);
}
}
DirEntry.java
package org.itstack.demo.jvm.classpath.impl;
import org.itstack.demo.jvm.classpat