英文:
Compiling/disassembling Java without creating a constant pool?
问题
我难以理解一些Java字节码指令的用法,部分原因是缺乏示例。相反,我使用javac
或Jasmin编译一些常规的Java代码,然后使用javap -c
来检查生成的字节码。
我的项目建立在一个为我优化字节码的框架上,因此我的代码生成器不必为我管理常量池。由于javap
输出中有许多对常量池的引用,如果我不必自己使用这些引用,那并不能真正澄清用法。
有没有一种方法可以在没有符号表(或任何对它的引用)的情况下获得反汇编的字节码?
详细说明如下,假设我们有以下代码:
public class MyConcatCode {
public static void main(String[] args){
String a ="Hello ";
String b ="World!";
String c = new StringBuilder().append(a).append(b).toString();
}
}
这将解析为:
...
0: ldc #7 // String Hello
2: astore_1
3: ldc #9 // String World!
5: astore_2
6: new #11 // class java/lang/StringBuilder
9: dup
10: invokespecial #13 // Method java/lang/StringBuilder."<init>":()V
13: aload_1
14: invokevirtual #14 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: aload_2
18: invokevirtual #14 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual #18 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_3
25: return
...
但我更希望有以下内容:
...
0: ldc Hello
2: astore_1
3: ldc World!
5: astore_2
6: new java/lang/StringBuilder
9: dup
10: invokespecial java/lang/StringBuilder."<init>":()V
13: aload_1
14: invokevirtual java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: aload_2
18: invokevirtual java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_3
25: return
...
如果像提供给我的框架一样,编译器在生成类似我第二个示例中描述的字节码后创建常量池,那么理论上可以获得不包含符号表的字节码,对吗?
英文:
I'm having trouble understanding the usage of some Java Bytecode Instructions, partially due to lack of examples. Instead, I use javac
or Jasmin to compile some regular Java code, and then I use javap -c
to inspect the generated bytecode.
My project is built on a framework that optimizes my bytecode for me, so my own code generator doesn't have to manage the constant pool for me. Since the javap
output contains a lot of reference to the constant pool, that doesn't really clear up the usage if I don't have to make use of those references myself.
Is there a way of getting disassembled bytecode without the symbol table (or any references to it)?
To elaborate, suppose we have the following code:
public class MyConcatCode {
public static void main(String[] args){
String a ="Hello ";
String b ="World!";
String c = new StringBuilder().append(a).append(b).toString();
}
}
This resolves to:
...
0: ldc #7 // String Hello
2: astore_1
3: ldc #9 // String World!
5: astore_2
6: new #11 // class java/lang/StringBuilder
9: dup
10: invokespecial #13 // Method java/lang/StringBuilder."<init>":()V
13: aload_1
14: invokevirtual #14 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: aload_2
18: invokevirtual #14 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual #18 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_3
25: return
...
But I'd much rather have the following:
...
0: ldc Hello
2: astore_1
3: ldc World!
5: astore_2
6: new java/lang/StringBuilder
9: dup
10: invokespecial java/lang/StringBuilder."<init>":()V
13: aload_1
14: invokevirtual java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
17: aload_2
18: invokevirtual java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: invokevirtual java/lang/StringBuilder.toString:()Ljava/lang/String;
24: astore_3
25: return
...
If, like the framework supplied to me, the compiler creates the constant pool after producing bytecode described in my second example, then it should be possible to get bytecode that doesn't contain a symbol table at all, right?
答案1
得分: 0
根据我理解你的问题,你只是在寻找一个不会打印常量池的字节码查看器。例如,不会打印常量池中字符串的引用,而是会将字符串内联。
-
Object web asm 包含一个实用程序类,用于反汇编提供的输入类。只需下载 asm jar 文件(热链接)和包含该实用程序的 asm-util jar 文件(热链接)。将这两个 jar 文件都添加到类路径中,然后运行
org.objectweb.asm.util.Textifier
类,并提供要反汇编的类文件的路径。
java -jar -cp asm-8.0.1.jar:asm-util-8.0.1.jar org.objectweb.asm.util.Textifier /path/to/your/file.class
-
字节码查看器 是一个用于处理字节码的强大工具,在查看菜单中,你可以选择 "Bytecode" 选项。它的表示会为你解析引用。
-
我认为 Krakatau 应该以相同的方式工作,但由于我不喜欢它们的语法和 Python,所以我从未深入研究过它。
英文:
As far as I understood your question, you're just looking for a bytecode viewer that does not print the constantpool. E.g. instead of printing a reference to a String in the constant pool, it will inlines the string.
-
Object web asm contains a utility class that disassambles the provided input class. Just download the asm jar (hotlink) and the asm-util jar containing the utility (hotlink). With both those jars on the classpath, run the
org.objectweb.asm.util.Textifier
class and provide the path to the classfile that you want to disassamble.
java -jar -cp asm-8.0.1.jar:asm-util-8.0.1.jar org.objectweb.asm.util.Textifier /path/to/your/file.class
-
Bytecode viewer is a powerful tool for working with bytecode in the view menu, you can select the option "Bytecode". Their representation resolves references for you.
-
I think Krakatau should work the same way, but since I didn't like their syntax and python, I've never had a deeper look into it.
专注分享java语言的经验与见解,让所有开发者获益!
评论