浅谈字符串常量池
1 对于直接赋值的字符串
public static void main(String[] args) {
String str1 = "hello";
String str2 = "hello";
System.out.println(str1==str2);//true
}
当执行str1=”hello”时,会直接在常量池中创建一个”hello”;
而当执行str2=”hello”时,字符串常量池中,已经有一个”hello”了,所以直接指向了”hello”.
2 对于使用构造方法创建字符串
public static void main(String[] args) {
String str1 = "hello";
String str2 = new String("hello");
System.out.println(str1==str2);//false
}
当执行str1=”hello”时,会直接在常量池中创建一个”hello”;
而当执行str2=new String(”hello”)时,会先检查常量池中是否有”hello”, 如果没有就在常量池中创建一个”hello”, 若常量池中已经存在”hello”就跳过此步,最后都要在堆中重新创建一个”hello”,并将str2执行堆中的”hello”.
3 编译前使用+号拼接
public static void main(String[] args) {
String str1 = "helloworld";
String str2 = "hello"+"world";
System.out.println(str1==str2);//true
}
对于此处的"hello"+“world”,在编译期间就拼接成为”helloworld”,即str2将指向常量池中的”helloworld”。
4 带变量的拼接
public static void main(String[] args) {
String str1 = "helloworld";
String str2 = "hello";
String str3 = str2+"world";
System.out.println(str1==str3);//false
}
对于此处的str2+"world"只有在运行时才会执行。
注意:
在使用类似于str2+=”world”类似的操作时,会在常量池中产生多余的字符串常量,这是不推荐的。
5 inter()入池方法
public static void main(String[] args) {
String str1 = new String("hello").intern();
String str2 = "hello";
System.out.println(str1==str2);//true
}
intern入池操作,会先检查常量池中是否有str1对应的”hello”,若没有则直接创建,并返回常量池中”hello”的引用。若存在,则直接返回常量池中”hello”的引用。
public static void main(String[] args) {
String str1 = new String("hello");
String str2 = "hello";
str1.intern();
System.out.println(str1==str2);//false
}
像上这段代码,str1在new的时候已经入池,而str1.intern()的返回值并没有变量接收,此时的str1.intern()就相当于废话了。