0

考虑代码中的两行:

...
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 行,方法被调用,并返回一个字符串对象,由 Ljava/lang/String 表示。这是正确的还是在这里,只有方法从索引为 #11 TO 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");不是一个实习字符串,所以它肯定不会在永久代内存区域上??

4

1 回答 1

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;并将结果 (a Ljava/lang/String;) 推送到堆栈上。

50:  pop

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

于 2012-11-10T07:46:11.077 回答