何时何地在Java源代码中初始化/存储String?

时间:2015-01-31 10:25:15

标签: java string jvm bytecode

这是我的源代码:

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        
}

我的问题是,在反汇编文本中看到的字符串在哪里?我只在评论中看到它。

3 个答案:

答案 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调用。