案例简述
本章节主要了解Java虚拟机从哪里寻找class文件并且读取class内字节码
环境准备
1、jdk 1.8.0
2、IntelliJ IDEA Community Edition 2018.3.1 x64
3、Notepad++ (插件安装HEX-Editor,用于查看class字节)
配置信息
1、调试配置
2.1、配置位置:Run/Debug Configurations -> program arguments
2.2、配置内容:-Xjre "C:Program FilesJavajdk1.8.0_161jre" E:itstackgitistack-demoitstack-demo-jvmitstack-demo-jvm-02argetest-classesorgitstackdemoestHelloWorld
代码示例
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
com.beust jcommander 1.72
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 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.classpath.Entry;import java.io.IOException;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;/** * http://www.itstack.org * create by fuzhengwei on 2019/4/24 * 目录形式的类路径 */public class DirEntry implements Entry { private Path absolutePath; public DirEntry(String path){ //获取绝对路径 this.absolutePath = Paths.get(path).toAbsolutePath(); } @Override public byte[] readClass(String className) throws IOException { return Files.readAllBytes(absolutePath.resolve(className)); } @Override public String toString() { return this.absolutePath.toString(); }}
WildcardEntry.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.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;import java.util.stream.Collectors;/** * http://www.itstack.org * create by fuzhengwei on 2019/4/24 * 通配符类路径,继承CompositeEntry */public class WildcardEntry extends CompositeEntry { public WildcardEntry(String path) { super(toPathList(path)); } private static String toPathList(String wildcardPath) { String baseDir = wildcardPath.replace("*