我无法理解某些 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
...
如果像提供给我的框架一样,编译器在生成第二个示例中描述的字节码后创建常量池,那么应该可以获得根本不包含符号表的字节码,对吧?