给定一个任意Class
实例,包括一个运行时生成的实例(.class
磁盘上没有文件),有没有办法获取类字节?
问问题
4279 次
2 回答
11
一般来说,这是不可能的。加载类时,JVM 解析其字节码并将其转换为内部表示。之后,JVM 可以自由地忘记原始字节码,这就是 HotSpot JVM 真正发生的事情。
但是,通过某些 hack,可以检查内部类表示并将其转换回有效的类文件(尽管它与原始字节码不同)。HotSpot JVM 中使用此类过程来重构类文件以用于检测目的。
作为概念证明,我编写了一个程序,该程序使用Unsafe
. 这仅用于演示;永远不要在生产中尝试这个。
编辑
您还可以使用Instrumentation API获取类文件数据(可能由 JVM 修改) 。这需要在 VM 引导程序(使用-javaagent
VM 选项)或在运行时通过动态附加机制加载 Java 代理。
以下是此类代理的示例:GetBytecode.java。
最后,如果您不介意使用本机代码,可以使用 JVMTI 函数GetConstantPool和GetBytecodes来获取特定 Java 方法的字节码。
这是一个JVMTI 示例。
于 2016-01-28T21:05:08.777 回答
2
String classFile = "/" + Object.class.getName().replace('.', '/') + ".class";
System.out.println(classFile);
URL url = Test.class.getResource(classFile);
System.out.println(url);
产生这个输出。
/java/lang/Object.class
jar:file:/usr/java/jdk1.8.0_60/jre/lib/rt.jar!/java/lang/Object.class
因此您可以使用url
以字节为单位读取。(不适用于运行时生成的类)
于 2016-01-28T20:56:12.513 回答