String常量池以及intern()方法详解

  • Post author:
  • Post category:其他




所有文章将同步到个人官方网站:


www.lifesmile.cn


一 字符串的创建方式有


2种

1.以字面量的形式创建:String a = “a”;以这种方式创建时,JVM会在编译的时候就把该字面量放到字符串常量池中,在java程序启动的时候就已经加载到内存中了.并且这个字符串常量池有个特点是有且仅有一份相同的字面量,在创建一个字面量时,首先会去字符串常量池中去找有没有相同的字面量,若有则返回常量池中的引用地址,若没有则在字符串常量池中创建一个字面量并返回这个的引用地址.

2.new的方式创建String b = new String(“b”),实际上这个动作创建了2个对象,一个通过”b”双引号创建的,另一个是通过new创建的,只是他们创建的时期不同,引号是在编译期存在字符串变量池,另一个是运行期存在堆中.





inter()


方法

当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。


三 看个例子


:

 public static void main(String[] args) {  

String s1 = "hello";  

String s2 = "hello";  

String s3 = "he" + "llo";  

String s4 = "hel" + new String("lo");  

String s5 = new String("hello");  

String s6 = s5.intern();  

String s7 = "h";  

String s8 = "ello";  

String s9 = s7 + s8;  

System.out.println(s1 == s2);// true -->①  

System.out.println(s1 == s3);// true -->②  

System.out.println(s1 == s4);// false-->③  

System.out.println(s1 == s9);// false-->④  

System.out.println(s4 == s5);// false-->⑤  

System.out.println(s1 == s6);// true -->⑥   

}  

①创建s1时已经放到字符串常量池中,再创建s2把常量池中的引用直接赋给s2,所以返回true.

②s3拼接的实际上就是”hello”,JVM在编译的时候就已经优化,所以返回true.

③new String(“lo”)实际上是创建了2个对象,一个放入字符串常量池中,一个放在堆中,s4 = “hel” + new String(“lo”)在运行期存在堆中,属于不同的引用,所以返回false.

④s9=s7+s8都是在运行期放入堆中,所以引用不同。返回false.

⑤s4和s5都是放在堆内不同位置,所以引用不同返回false.

⑥s6调用inern()方法,字符串线程池中有,所以直接返回字符串线程池中的引用,所以返回true.


注意:

因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。 new String()和new String(””)都是申明一个新的空字符串,是空串不是null;


看完做过小测试:

test1:

public static void main(String[] args){

    String a = "a1";

    String b = "a"+ 1;

    System.out.println(a==b);//true

}

test2:

public static void main(String[] args){

    String a = "ab";

    String bb = "b";

    String b = "a"+ bb; //编译器不能确定为常量

    System.out.println(a==b);//false

}

test3:

public static void main(String[] args){

    String a = "ab";

    final String bb = "b";

    String b = "a"+ bb; //bb加final后是常量,可以在编译器确定b

    System.out.println(a==b);//true

}

test4:




public static void main(String[] args){

    String a = "ab";

    final String bb = getBB();

    String b = "a"+ bb;//bb是通过函数返回的,虽然知道它是final的,但不知道具体是啥,要到运行期才知道bb的值

    System.out.println(a==b);//false

}

private static String getBB(){ return "b"; }



test5:

private static String a = "ab";

public static void main(String[] args){

    String s1 = "a";

    String s2 = "b";

    String s = s1 + s2;//+的用法

    System.out.println(s == a);//flase

    System.out.println(s.intern() == a);//intern的含义 true

}



test6:

public static void main(String[] args){

    String s1 = "a";

    String s2 = "b";

    String s = s1 + s2;

    System.out.println(s == a);

    System.out.println(s.intern() == a);

    System.out.println(s.intern() == a.intern());

}//flase false true



所有文章将同步到个人官方网站:


www.lifesmile.cn

参考:

http://www.cnblogs.com/kkgreen/archive/2011/08/24/2151450.html

https://www.cnblogs.com/tongkey/p/8587060.html

http://www.cnblogs.com/wanlipeng/archive/2010/10/21/1857513.html



版权声明:本文为sinat_16658263原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。