0x01 前言
想获取某个类的class字节码那么我们可以使用此方法
# 目录结构
├── ClassLoader
│ └── CustomClassLoaderAddClassFile
│ ├── Test.java (用来做测试的方法)
│ ├── ClassByte.java (用来获取类的字节码的)
├── ClTestClass.class (一个编译好的类文件,用来被获取字节码用的)
0x02 ClassByte (用来获取类的字节码的)
package ClassLoader.CustomClassLoaderAddClassFile;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
public class ClassByte {
public String getFileByte(String filePath) {
byte[] classBytes = null;
Path path = null;
try {
path = Paths.get(new URI(filePath));
classBytes = Files.readAllBytes(path);
} catch (IOException | URISyntaxException e) {
e.printStackTrace();
}
// 返回类字节码
return Arrays.toString(classBytes);
}
}
0x03 ClTestClass.class (用来被获取字节码用的)
// 未编译前的源码
package ClassLoader.CustomClassLoaderAddClassFile;
public class ClTestClass {
public void show() {
System.out.println("show test!");
}
}
0x04 例子
0x04.1 例子: 获取某个类字节码
// 例子: 获取 ClTestClass.class 类的字节码
// 注意: 要编译过的才能获取
// /Users/pmiaowu/Desktop/ClTestClass.class 这个路径 取决与你把 ClTestClass.class放那里
package ClassLoader.CustomClassLoaderAddClassFile;
public class Test {
public static void main(String[] args) {
String cPath = "file:///Users/pmiaowu/Desktop/ClTestClass.class";
ClassByte cbs = new ClassByte();
System.out.println(cbs.getFileByte(cPath));
}
}
// 执行结果
[-54, -2, -70, -66, 0, 0, 0, 51, 0, 31, 10, 0, 6, 0, 17, 9, 0, 18, 0, 19, 8, 0, 20, 10, 0, 21, 0, 22, 7, 0, 23, 7, 0, 24, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0, 3, 40, 41, 86, 1, 0, 4, 67, 111, 100, 101, 1, 0, 15, 76, 105, 110, 101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 101, 1, 0, 18, 76, 111, 99, 97, 108, 86, 97, 114, 105, 97, 98, 108, 101, 84, 97, 98, 108, 101, 1, 0, 4, 116, 104, 105, 115, 1, 0, 55, 76, 67, 108, 97, 115, 115, 76, 111, 97, 100, 101, 114, 47, 67, 117, 115, 116, 111, 109, 67, 108, 97, 115, 115, 76, 111, 97, 100, 101, 114, 65, 100, 100, 67, 108, 97, 115, 115, 70, 105, 108, 101, 47, 67, 108, 84, 101, 115, 116, 67, 108, 97, 115, 115, 59, 1, 0, 4, 115, 104, 111, 119, 1, 0, 10, 83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1, 0, 16, 67, 108, 84, 101, 115, 116, 67, 108, 97, 115, 115, 46, 106, 97, 118, 97, 12, 0, 7, 0, 8, 7, 0, 25, 12, 0, 26, 0, 27, 1, 0, 10, 115, 104, 111, 119, 32, 116, 101, 115, 116, 33, 7, 0, 28, 12, 0, 29, 0, 30, 1, 0, 53, 67, 108, 97, 115, 115, 76, 111, 97, 100, 101, 114, 47, 67, 117, 115, 116, 111, 109, 67, 108, 97, 115, 115, 76, 111, 97, 100, 101, 114, 65, 100, 100, 67, 108, 97, 115, 115, 70, 105, 108, 101, 47, 67, 108, 84, 101, 115, 116, 67, 108, 97, 115, 115, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 121, 115, 116, 101, 109, 1, 0, 3, 111, 117, 116, 1, 0, 21, 76, 106, 97, 118, 97, 47, 105, 111, 47, 80, 114, 105, 110, 116, 83, 116, 114, 101, 97, 109, 59, 1, 0, 19, 106, 97, 118, 97, 47, 105, 111, 47, 80, 114, 105, 110, 116, 83, 116, 114, 101, 97, 109, 1, 0, 7, 112, 114, 105, 110, 116, 108, 110, 1, 0, 21, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 86, 0, 33, 0, 5, 0, 6, 0, 0, 0, 0, 0, 2, 0, 1, 0, 7, 0, 8, 0, 1, 0, 9, 0, 0, 0, 47, 0, 1, 0, 1, 0, 0, 0, 5, 42, -73, 0, 1, -79, 0, 0, 0, 2, 0, 10, 0, 0, 0, 6, 0, 1, 0, 0, 0, 3, 0, 11, 0, 0, 0, 12, 0, 1, 0, 0, 0, 5, 0, 12, 0, 13, 0, 0, 0, 1, 0, 14, 0, 8, 0, 1, 0, 9, 0, 0, 0, 55, 0, 2, 0, 1, 0, 0, 0, 9, -78, 0, 2, 18, 3, -74, 0, 4, -79, 0, 0, 0, 2, 0, 10, 0, 0, 0, 10, 0, 2, 0, 0, 0, 5, 0, 8, 0, 6, 0, 11, 0, 0, 0, 12, 0, 1, 0, 0, 0, 9, 0, 12, 0, 13, 0, 0, 0, 1, 0, 15, 0, 0, 0, 2, 0, 16]
0x04.2 使用的类字节码并反射调用方法
// 例子: 使用ClTestClass类的字节码进行实例化并反射调用show方法
package ClassLoader.CustomClassLoaderAddClassFile;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
// loadClassName = ClTestClass.class类,源码里面写的 package路径+被调用类的类名称
String loadClassName = "ClassLoader.CustomClassLoaderAddClassFile.ClTestClass";
// ClTestClass.class类的字节码
byte[] classBytes = new byte[]{
-54, -2, -70, -66, 0, 0, 0, 51, 0, 31, 10, 0, 6, 0, 17, 9, 0, 18, 0, 19, 8, 0, 20, 10, 0, 21, 0, 22, 7, 0, 23, 7, 0, 24, 1, 0, 6, 60, 105, 110, 105, 116, 62, 1, 0, 3, 40, 41, 86, 1, 0, 4, 67, 111, 100, 101, 1, 0, 15, 76, 105, 110, 101, 78, 117, 109, 98, 101, 114, 84, 97, 98, 108, 101, 1, 0, 18, 76, 111, 99, 97, 108, 86, 97, 114, 105, 97, 98, 108, 101, 84, 97, 98, 108, 101, 1, 0, 4, 116, 104, 105, 115, 1, 0, 55, 76, 67, 108, 97, 115, 115, 76, 111, 97, 100, 101, 114, 47, 67, 117, 115, 116, 111, 109, 67, 108, 97, 115, 115, 76, 111, 97, 100, 101, 114, 65, 100, 100, 67, 108, 97, 115, 115, 70, 105, 108, 101, 47, 67, 108, 84, 101, 115, 116, 67, 108, 97, 115, 115, 59, 1, 0, 4, 115, 104, 111, 119, 1, 0, 10, 83, 111, 117, 114, 99, 101, 70, 105, 108, 101, 1, 0, 16, 67, 108, 84, 101, 115, 116, 67, 108, 97, 115, 115, 46, 106, 97, 118, 97, 12, 0, 7, 0, 8, 7, 0, 25, 12, 0, 26, 0, 27, 1, 0, 10, 115, 104, 111, 119, 32, 116, 101, 115, 116, 33, 7, 0, 28, 12, 0, 29, 0, 30, 1, 0, 53, 67, 108, 97, 115, 115, 76, 111, 97, 100, 101, 114, 47, 67, 117, 115, 116, 111, 109, 67, 108, 97, 115, 115, 76, 111, 97, 100, 101, 114, 65, 100, 100, 67, 108, 97, 115, 115, 70, 105, 108, 101, 47, 67, 108, 84, 101, 115, 116, 67, 108, 97, 115, 115, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 79, 98, 106, 101, 99, 116, 1, 0, 16, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 121, 115, 116, 101, 109, 1, 0, 3, 111, 117, 116, 1, 0, 21, 76, 106, 97, 118, 97, 47, 105, 111, 47, 80, 114, 105, 110, 116, 83, 116, 114, 101, 97, 109, 59, 1, 0, 19, 106, 97, 118, 97, 47, 105, 111, 47, 80, 114, 105, 110, 116, 83, 116, 114, 101, 97, 109, 1, 0, 7, 112, 114, 105, 110, 116, 108, 110, 1, 0, 21, 40, 76, 106, 97, 118, 97, 47, 108, 97, 110, 103, 47, 83, 116, 114, 105, 110, 103, 59, 41, 86, 0, 33, 0, 5, 0, 6, 0, 0, 0, 0, 0, 2, 0, 1, 0, 7, 0, 8, 0, 1, 0, 9, 0, 0, 0, 47, 0, 1, 0, 1, 0, 0, 0, 5, 42, -73, 0, 1, -79, 0, 0, 0, 2, 0, 10, 0, 0, 0, 6, 0, 1, 0, 0, 0, 3, 0, 11, 0, 0, 0, 12, 0, 1, 0, 0, 0, 5, 0, 12, 0, 13, 0, 0, 0, 1, 0, 14, 0, 8, 0, 1, 0, 9, 0, 0, 0, 55, 0, 2, 0, 1, 0, 0, 0, 9, -78, 0, 2, 18, 3, -74, 0, 4, -79, 0, 0, 0, 2, 0, 10, 0, 0, 0, 10, 0, 2, 0, 0, 0, 5, 0, 8, 0, 6, 0, 11, 0, 0, 0, 12, 0, 1, 0, 0, 0, 9, 0, 12, 0, 13, 0, 0, 0, 1, 0, 15, 0, 0, 0, 2, 0, 16
};
ByteClassLoader loader = new ByteClassLoader(loadClassName, classBytes);
try {
// 加载类
Class testClass = loader.loadClass(loadClassName);
// 实例化
Object testInstance = testClass.newInstance();
// 获取show方法
Method method = testClass.getMethod("show");
// 调用show方法
method.invoke(testInstance);
} catch (Exception e) {
e.printStackTrace();
}
}
}
// 运行结果
show test!