String 简述及intern方法

  https://docs.oracle.com/javase/8/docs/api/java/lang/String.html

  在JAVA中有8种基本类型和一种特殊字符类型:String。这些类型为了运行更快,更节省内存,使用了常量池的概念。

  String声明为final,表示不可继承,所有的属性也是final类型。字符串常量:string一经创建值便不可修改。由于它的不可变性,因此string相关的拼接,截取等操作都会产生新的对象。String底层使用char数组方式进行存储。

  常见生成string方式:

  1、String s = new String("abc"); 创建了二个对象:1、第一个对象 "abc"对应常量池中;第二个对象 在JAVA heap中的String对象。

   2、String a = "11";  声明使用双引号直接存储到常量池中。

   3、String.valueOf(1);   底层使用new String(char[])的方式实现转换

  String#intern方法

  native String intern():目的是提示 JVM 把相应字符串缓存起来,以备重复使用。。

  intern() 是一种显式排重的机制。需要使用者显式调用它,这样一是不方便,二是每次显式比较麻烦。

  要注意的是,String的String Pool是一个固定大小的Hashtable,默认值大小长度是1009,如果放进String Pool的String非常多,就会造成Hash冲突严重,从而导致链表会很长,而链表长了后直接会造成的影响就是当调用String.intern时性能会大幅下降(因为要一个一个找)。

在 jdk6中StringTable是固定的,就是1009的长度,所以如果常量池中的字符串过多就会导致效率下降很快。

在jdk7中,StringTable的长度可以通过一个参数指定:    -XX:StringTableSize=99991

 1  public static void main(String[] args)  {
 2         String s1 = new String("1");
 3         String s2 = "1";
 4         s1.intern();
 5         System.out.println(s1 == s2);
 6 
 7         String s3 = new String("1") + new String("2");
 8         String s4 = "12";
 9         s3.intern();
10         System.out.println(s3 == s4);
11     }

输出结果: false  false

代码行7:生成两个对象,分别对应常量池"1","2",  JAVA heap中的s3引用指向的对象。 s3引用指向对象的内容是"12",但是此时常量池中没"12"对象。"Java语言为字符串连接运算符(+)以及将其他对象转换为字符串提供了特殊的支持。字符串连接是通过StringBuilder(或StringBuffer)类及其append方法实现的。字符串转换是通过toString方法实现的"

代码行8:s4是显式声明,直接向常量池查找不到,则创建对象。

代码行9:intern()返回字符串对象的规范表示形式。在调用intern方法时,如果池中已经包含了由equals(object)方法确定的与该字符串对象相等的字符串,则返回池中的字符串。否则,该字符串对象将被添加到池中,并返回对该字符串对象的引用。

如果s4 变换下位置

 1  public static void main(String[] args)  {
 2         String s = new String("1");
 3         String s2 = "1";
 4         s.intern();
 5         System.out.println(s == s2);
 6 
 7         String s3 = new String("1") + new String("2");
 8         s3.intern();
 9         String s4 = "12";
10         System.out.println(s3 == s4);
11     }

输出结果: false true  (以上基于jdk8运行)

代码行8:先调用intern(),会在常量池创建对象并返回对象引用。

代码行9:s4声明式显示,在常量池中找到并返回对象。

因此,s3==s4是指向同一个对象。

原文地址:https://www.cnblogs.com/song27/p/13201482.html