这是我的源代码:
public class Koray {
public static void main(String [] args) {
System.out.println("This is a sample program.");
}
}
当我编译它时,我得到字节码。当我用十六进制查看器查看字节码时,我看到了部分:
19 54 68 69 73 20 69 73 20 61 20 73 61 6D 70 6C 65 20 70 72 6F 67 72 61 6D 2E
可以读作
This is a sample program.
如果字节被解释为字符。
当我做的时候
javap -c Koray.class
反汇编我看到的这个课程:
Compiled from "Koray.java"
public class Koray {
public Koray();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String This is a sample program.
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: bipush 10
10: istore_1
11: return
}
我的问题是,在反汇编文本中看到的字符串在哪里?我只在评论中看到它。
答案 0 :(得分:4)
ldc #3; //String This is a sample program.
此行使用opcode
ldc
,它将常量加载到操作数堆栈上。此时,我们将加载常量池表的索引#3
中的任何常量。
常量池表是存储大多数文字常量值的位置。 (ref)命令javap -c -verbose <classfile>
提供常量池表的输出。
示例输出:
const #22 = String #23; // This is a sample program
const #23 = Asciz This is a sample program;
VM Spec(http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html)的更多信息:
constant_pool 是一个结构表(§4.4),表示各种字符串常量,类和接口名称,字段名称和 ClassFile结构中引用的其他常量 及其子结构。每个constant_pool表条目的格式是 由其第一个“标记”字节表示。 constant_pool表已编制索引 从1到constant_pool_count-1。
答案 1 :(得分:4)
ldc #3
加载存储在常量池中的字符串常量,该常量池是一个单独的表,用于存储String
文字和类名等常量。
请参阅JVM规范中的http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.4:
constant_pool是一个结构表(第4.4节),表示各种字符串常量,类和接口名称,字段名称以及ClassFile结构及其子结构中引用的其他常量。每个constant_pool表条目的格式由其第一个“标记”字节表示。
您可以使用javap -verbose ClassName
查看字符串表。
示例输出类似于:
Compiled from "Test.java"
public class tests.Test extends java.lang.Object
SourceFile: "Test.java"
minor version: 0
major version: 50
Constant pool:
const #1 = class #2; // tests/Test
const #2 = Asciz tests/Test;
const #3 = String #4; // This is a sample program.
...
答案 2 :(得分:4)
看到ldc
instruction?它从运行时常量池中加载常量。那是你的字符串存储的地方。
要同时打印常量池,请将-verbose
option添加到javap调用。