Java 如何从类中获取字节码作为字节数组

Java 如何从类中获取字节码作为字节数组,java,jvm,java-bytecode-asm,jvm-bytecode,Java,Jvm,Java Bytecode Asm,Jvm Bytecode,给定一个任意的类实例,包括一个运行时生成的实例(磁盘上没有.Class文件),有没有办法获取类字节 String classFile = "/" + Object.class.getName().replace('.', '/') + ".class"; System.out.println(classFile); URL url = Test.class.getResource(classFile); System.out.println(url); 生成此输出 /java/lang/Obj

给定一个任意的
实例,包括一个运行时生成的实例(磁盘上没有
.Class
文件),有没有办法获取类字节

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
读取字节。(不适用于运行时生成的类)

通常,这是不可能的。加载类时,JVM解析其字节码并将其转换为内部表示。在这之后,JVM可以自由地忘记原始字节码,这就是HotSpot JVM真正发生的事情

然而,使用某些黑客可以检查内部类表示并将其转换回有效的类文件(尽管它与原始字节码不同)。在HotSpot JVM中,这样的过程用于为重新构建类文件

作为概念证明,我编写了使用
safe
从JVM内存中提取已加载类的已处理字节码。这只是一个演示;不要在生产中尝试这个

编辑

您还可以使用获取类文件数据(可能由JVM修改)。这需要在VM引导时(使用VM选项)或在运行时通过加载Java代理

以下是此类代理的一个示例:

最后,如果您不介意使用本机代码,可以使用JVMTI函数和获取特定Java方法的字节码


这是一个。

你看过了吗?顺便说一句,从JDK 9开始这将是无效的,因为不再有带有原始字节码的rt.jar了。或者很简单:
Object.class.getResource(“Object.class”)
,或者对于任意的
对象:
classObj.getResource(classObj.getSimpleName()+“.class”)
@apangin:这将继续使用Java9,因为这是抽象的要点。只是URL不再有一个
jar:
,而是一个
jrt:
方案+1@apangin有没有一种方法可以使用其字节码和常量池(使用jvmti)生成方法定义?@kumarD不确定您的意思。常量池是类的属性,而字节码是方法的属性。您希望以什么形式获得方法定义?