StringTable面试题:
String s1 = "a";
String s2 = "b";
String s3 = "a" + "b";
String s4 = s1 + s2;
String s5 = "ab";
String s6 = s4.intern();
// 问
System.out.println(s3 == s4);
System.out.println(s3 == s5);
System.out.println(s3 == s6);
String x2 = new String("c") + new String("d");
String x1 = "cd";
x2.intern();
// 问,如果调换了【最后两行代码】的位置呢,如果是jdk1.6呢
System.out.println(x1 == x2);
public class Demo1_22 {
public static void main(String[] args) {
String s1 = "a";
String s2 = "b";
String s3 = "ab";
String s4 = s1 + s2;
String s5 = "a" + "b";
System.out.println(s3 == s5);
}
}
反编译class文件后
javap -v Demo1_22.class
Classfile /Users/eistert/Desktop/JVM/JVM/code/jvm/out/production/jvm/cn/itcast/jvm/t1/stringtable/Demo1_22.class
Last modified Aug 1, 2021; size 985 bytes
MD5 checksum a5eb84bf1a7d8a1e725491f36237777b
Compiled from "Demo1_22.java"
public class cn.itcast.jvm.t1.stringtable.Demo1_22
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #12.#36
#2 = String #37
#3 = String #38
#4 = String #39
#5 = Class #40
#6 = Methodref #5.#36
#7 = Methodref #5.#41
#8 = Methodref #5.#42
#9 = Fieldref #43.#44
#10 = Methodref #45.#46
#11 = Class #47
#12 = Class #48
#13 = Utf8 <init>
#14 = Utf8 ()V
#15 = Utf8 Code
#16 = Utf8 LineNumberTable
#17 = Utf8 LocalVariableTable
#18 = Utf8 this
#19 = Utf8 Lcn/itcast/jvm/t1/stringtable/Demo1_22;
#20 = Utf8 main
#21 = Utf8 ([Ljava/lang/String;)V
#22 = Utf8 args
#23 = Utf8 [Ljava/lang/String;
#24 = Utf8 s1
#25 = Utf8 Ljava/lang/String;
#26 = Utf8 s2
#27 = Utf8 s3
#28 = Utf8 s4
#29 = Utf8 s5
#30 = Utf8 StackMapTable
#31 = Class #23
#32 = Class #49
#33 = Class #50
#34 = Utf8 SourceFile
#35 = Utf8 Demo1_22.java
#36 = NameAndType #13:#14
#37 = Utf8 a
#38 = Utf8 b
#39 = Utf8 ab
#40 = Utf8 java/lang/StringBuilder
#41 = NameAndType #51:#52
#42 = NameAndType #53:#54
#43 = Class #55
#44 = NameAndType #56:#57
#45 = Class #50
#46 = NameAndType #58:#59
#47 = Utf8 cn/itcast/jvm/t1/stringtable/Demo1_22
#48 = Utf8 java/lang/Object
#49 = Utf8 java/lang/String
#50 = Utf8 java/io/PrintStream
#51 = Utf8 append
#52 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder;
#53 = Utf8 toString
#54 = Utf8 ()Ljava/lang/String;
#55 = Utf8 java/lang/System
#56 = Utf8 out
#57 = Utf8 Ljava/io/PrintStream;
#58 = Utf8 println
#59 = Utf8 (Z)V
{
public cn.itcast.jvm.t1.stringtable.Demo1_22();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1
4: return
LineNumberTable:
line 4: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcn/itcast/jvm/t1/stringtable/Demo1_22;
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=3, locals=6, args_size=1
0: ldc #2
2: astore_1
3: ldc #3
5: astore_2
6: ldc #4
8: astore_3
9: new #5
12: dup
13: invokespecial #6
16: aload_1
17: invokevirtual #7
20: aload_2
21: invokevirtual #7
24: invokevirtual #8
27: astore 4
29: ldc #4
31: astore 5
33: getstatic #9
36: aload_3
37: aload 5
39: if_acmpne 46
42: iconst_1
43: goto 47
46: iconst_0
47: invokevirtual #10
50: return
LineNumberTable:
line 11: 0
line 12: 3
line 13: 6
line 14: 9
line 15: 29
line 17: 33
line 21: 50
LocalVariableTable:
Start Length Slot Name Signature
0 51 0 args [Ljava/lang/String;
3 48 1 s1 Ljava/lang/String;
6 45 2 s2 Ljava/lang/String;
9 42 3 s3 Ljava/lang/String;
29 22 4 s4 Ljava/lang/String;
33 18 5 s5 Ljava/lang/String;
StackMapTable: number_of_entries = 2
frame_type = 255
offset_delta = 46
locals = [ class "[Ljava/lang/String;", class java/lang/String, class java/lang/String, class java/lang/String, class java/lang/String, class java/lang/String ]
stack = [ class java/io/PrintStream ]
frame_type = 255
offset_delta = 0
locals = [ class "[Ljava/lang/String;", class java/lang/String, class java/lang/String, class java/lang/String, class java/lang/String, class java/lang/String ]
stack = [ class java/io/PrintStream, int ]
}
SourceFile: "Demo1_22.java"
String s4 = s1 + s2; 对应的指令 

javac 在编译期间的优化,结果已经在编译期确定为ab 
StringTable字符串延迟加载
public class TestString {
public static void main(String[] args) {
int x = args.length;
System.out.println();
System.out.print("1");
System.out.print("2");
System.out.print("3");
System.out.print("4");
System.out.print("5");
System.out.print("6");
System.out.print("7");
System.out.print("8");
System.out.print("9");
System.out.print("0");
System.out.print("1");
System.out.print("2");
System.out.print("3");
System.out.print("4");
System.out.print("5");
System.out.print("6");
System.out.print("7");
System.out.print("8");
System.out.print("9");
System.out.print("0");
System.out.print(x);
}
}


可以使用 intern 方法,主动将串池中还没有的字符串对象放入串池
1.8 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有则放入串池, 会把串
池中的对象返回
1.6 将这个字符串对象尝试放入串池,如果有则并不会放入,如果没有会把此对象复制一份,
放入串池, 会把串池中的对象返回
public class Demo1_23 {
public static void main(String[] args) {
String x = "ab";
String s = new String("a") + new String("b");
String s2 = s.intern();
System.out.println( s2 == x);
System.out.println( s == x );
}
}



|