读取Java字节码指令:数字是什么意思?
我在阅读java字节码时看到:读取Java字节码指令:数字是什么意思?,java,bytecode,Java,Bytecode,我在阅读java字节码时看到: getfield #5 (Field java.lang.String name) #5是什么意思 如何用字节码编写程序?指令(IIRC)在类文件的常量池中引用关于应该查找哪个字段的信息。这里的#5表示“常量池条目编号5”,这个常量池包含这样的信息:“查找java.lang.String类型的字段name)。原因是它保持getfield指令的大小不变,而不管要查找的字段的名称或类型如何 我不确定我是否理解你所说的“如何用字节码编写程序?”这是一个相当开放的问题;
getfield #5 (Field java.lang.String name)
#5
是什么意思
如何用字节码编写程序?指令(IIRC)在类文件的常量池中引用关于应该查找哪个字段的信息。这里的#5表示“常量池条目编号5”,这个常量池包含这样的信息:“查找
java.lang.String
类型的字段name
)。原因是它保持getfield
指令的大小不变,而不管要查找的字段的名称或类型如何
我不确定我是否理解你所说的“如何用字节码编写程序?”这是一个相当开放的问题;它类似于问如何用任何语言编写程序,需要大量的学习。你可能想研究Java汇编程序,它可以大大简化这一过程
希望这有帮助!Java类文件和字节码
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String hello world
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
Java类文件(字节码文件)由不同的组件组成:
- 幻数:0xCAFEBABE
- 类文件格式的版本:类文件的次要版本和主要版本
- 常量池:类的常量池
- (……)
- 字段:类中的任何字段
- 方法:类中的任何方法
- 属性:类的任何属性(例如源文件的名称等)
getfield #number -> FieldRef -> NameAndType -> Utf8 -> string
因此,不是在每个getfield
指令中保存整个字符串,而是保存一个数字。这提高了解释器(或JIT)的性能和类文件的空间
手写字节码
使用此工具可以将手写字节码组装到类文件中(它包含许多示例):
它是常量池索引,常量池存储类文件的所有信息,JVM指令使用索引引用类信息,如字段、方法 我将使用hello world示例演示其工作原理: 来源:
System.out.println("hello world");
字节码
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String hello world
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
字节码指令的格式为指令常量池索引
Constant pool:
#4 = Methodref #28.#29 // java/io/PrintStream.println:(Ljava/lang/String;)V
#28 = Class #36 // java/io/PrintStream
#29 = NameAndType #37:#38 // println:(Ljava/lang/String;)V
#36 = Utf8 java/io/PrintStream
#37 = Utf8 println
#38 = Utf8 (Ljava/lang/String;)V
因此,此指令将调用索引为4的方法
invokevirtual#4
索引4是//java/io/PrintStream.println:(Ljava/lang/String;)V
如果我们遵循常量池中的引用,我们会发现所有信息都存储在字符串中,并组合成复杂类型,如方法、字段、类
用Java编写并编译程序。您希望实现什么?类似ASM的JVM优化?