字符串由java.sql.ResultSet.getString()返回及其字节码解释

时间:2012-11-10 07:16:32

标签: java string bytecode

考虑代码中的两行:

...
rs.next();  //rs is ResultSet interface.
rs.getString("name");
...

javap 生成的字节代码为:

...
35:  invokeinterface #9,  1; //InterfaceMethod java/sql/ResultSet.next:()Z
   40:  pop
   41:  aload   4
   43:  ldc     #10; //String name
   45:  invokeinterface #11,  2; //InterfaceMethod java/sql/ResultSet.getString:
(Ljava/lang/String;)Ljava/lang/String;
   50:  pop
   51:  aload_2
   52:  invokeinterface #12,  1; //InterfaceMethod java/sql/Connection.close:()V

 ...

我正在尝试解释这个字节码。

对于行rs.getString("name");,字节码从第43行开始到第51行。

1)第45行方法是 INVOKED ,返回一个字符串对象,由Ljava / lang / String表示。这是正确的 OR ,只有方法正在从索引#11到STACK的常量池加载并在第50行执行???

2)rs.getString("name");返回的字符串对象在哪里?在堆栈或堆上,因为我认为aload_2正在堆栈上推送一些值。

其实在这里,我对以下内容感到困惑:

如果我有:

 ...
rs.next();
rs.getString("name");
rs.getString("name");
rs.getString("name");
rs.getString("name");
...10 more times...
...

并且都返回相同的名称。然后将有10个不同的字符串对象具有相同的值。因此它将是内存浪费,并且是使用intern()的情况。但如果这些将在堆栈上,那么它仍将被视为内存浪费并需要intern()???

3)我认为rs.getString("name");返回的字符串对象不是一个实习字符串,所以肯定它不会在永久代存储区中?

1 个答案:

答案 0 :(得分:2)

呼叫字节码的相关部分

rs.getString("name")

41:  aload   4
43:  ldc     #10; //String name
45:  invokeinterface #11,  2; //InterfaceMethod java/sql/ResultSet.getString:(Ljava/lang/String;)Ljava/lang/String;
50:  pop

一次取一行操作码

41:  aload   4

将存储在局部变量#4(rs)中的对象推送到堆栈

43:  ldc     #10; //String name

将字符串常量"name"推入堆栈

45:  invokeinterface #11,  2; //InterfaceMethod java/sql/ResultSet.getString:(Ljava/lang/String;)Ljava/lang/String;

弹出堆栈中的前2项以调用接口方法java/sql/ResultSet.getString:(Ljava/lang/String;)Ljava/lang/String;并将结果(Ljava/lang/String;)推送到堆栈上。

50:  pop

然后将前一个方法的结果从堆栈中弹出。