考虑代码中的两行:
...
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");
返回的字符串对象不是一个实习字符串,所以肯定它不会在永久代存储区中?
答案 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
然后将前一个方法的结果从堆栈中弹出。