zoukankan      html  css  js  c++  java
  • 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是指向同一个对象。

  • 相关阅读:
    【排序算法汇总】
    Redis是否安装
    分布式与集群
    Redis学习
    简单算法定义见解
    KMP算法
    红黑树
    JSP与Servlet的关系
    7、创建图及图的遍历(java实现)
    6、二叉树树(java实现)
  • 原文地址:https://www.cnblogs.com/song27/p/13201482.html
Copyright © 2011-2022 走看看