89竹林 发表于 2015-2-16 10:08

java为String类提供了String池

java的String是不可变类。为了提高效率,java为String类提供了String池。

1. 当我们使用形如String s = "abc"的代码为字符串赋值时,JVM首先会检查字符串常量池中是否有"abc"这个字符串,如果有就直接将其地址赋给s;若没有,则在Stirng池中创建一个字符串对象“abc”,再将其地址赋给s。

例如:
public static void main(String[] args) {      String s1="hello";      String s2="hello";      String s3="he"+"llo";      System.out.println(s1==s2);      System.out.println(s2==s3);}上述代码中,执行String s1 = "hello"时JVM在String池中创建了“hello”对象;当执行到String s2="hello"时,因为此时String池中已经有了“hello”,编译器就直接将“hello”的地址赋给s2。因此s1、s2指向了同一个对象,所以输出为true。S3也是同样道理。


是否入池要看情况而定,等号右边如果是常量则入池,非常量则不入池
String s3 = "a" + "b"; //"a"是常量,"b"是常量,常量+常量=常量,所以会入池.
String s4 = s1 + "b";//s1是变量,"b"是常量,变量+常量!=常量,所以不会入池.


2. 当使用String s=new String("");这种形式赋值时,实际上产生了两个对象。
例如:String s=new String("abc"),此时先是在String常量池中产生了一个“abc”对象,然后new String()又在堆中分配了内存空间,将常量区中的“abc"复制一份给了堆中的String对象。因此这段代码产生了两个对象,一个在常量区、一个在堆区。
public static void main(String[] args) {      String s1="hello";      String s2=new String("hello");      System.out.println(s1==s2);}这里s1指向的是常量区中的”hello“,s2指向的是堆中的”hello“,因此输出为false。


3. java.lang.String的intern()方法
一个初始时为空的字符串池,它由类 String 私有地维护。当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。
它遵循对于任何两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。

String str1 = "a";String str2 = "bc";String str3 = "a" + "bc";String str4 = str1 + str2;System.out.println(str3 == str4);// falsestr4 = (str1 + str2).intern();System.out.println(str3 == str4);//true
页: [1]
查看完整版本: java为String类提供了String池