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!
