• java String的intern()方法


    intern()方法用于将字符串对象加入常量池中。

        public native String intern();

    intern()方法返回的是一个常量池中的String对象(即常量池中某个String对象的引用)。

            String s = new String("1");
            s.intern();

    s是一个位于堆中的String对象,其字符串值为 "1" , 调用s的intern()方法,可在常量池中创建一个字符串值与s相同的String对象。

    创建过程为:

    首先查找常量池中是否已存在值为 "1" 的String对象,若存在则返回该对象。

    若不存在,在JDK1.6及之前,会在常量池中创建一个新的值为 "1" 的String对象,并返回该对象。

                     在JDK1.7及之后,会将s的引用添加至常量池中,堆中的String对象s间接的成为了常量池中的一员,此时返回的是对象s。

    示例:

        public static void main(String[] args) {
    
            String s = new String("1");
            s.intern();
            String s2 = "1";
            System.out.println(s == s2);
    
            String s3 = new String("1") + new String("1");
            s3.intern();
            String s4 = "11";
            System.out.println(s3 == s4);
    
        }

    jdk1.6下输出结果为 false  false

    jdk1.7下输出结果为 false  true

    jdk1.6下解释:

    jdk6中的常量池是放在 Perm 区中的,Perm区和正常的 JAVA Heap 区域是完全分开的。使用引号声明的字符串都是会直接在字符串常量池中生成,而 new 出来的 String 对象是放在 JAVA Heap 区域。

    String s = new String("1"); 创建了两个String对象,一个位于堆中即是s,一个位于常量池中,值为"1"。
    String s2 = "1"; 由于常量池中已经存在值为"1"的String对象,所以s2指向的是常量池中的String对象。

    所以
    s == s2 结果为false,s与s2指向的并不是同一个对象。


    String s3 = new String("1") + new String("1"); 在堆中创建了一个值为"11"的String对象即是s3。
    s3.intern();由于常量池中没有值为"11"的String对象,所以在池中创建了一个。
    String s4 = "11";常量池中已经存在值为"11"的String对象,所以s4指向了常量池中的String对象。
    所以s3 == s4 结果为false,s3与s4指向的并不是同一个对象。

     jdk1.7下解释:

            String s = new String("1");
            s.intern();
            String s2 = "1";
            System.out.println(s == s2);
    
            String s3 = new String("1") + new String("1");
            s3.intern();
            String s4 = "11";
            System.out.println(s3 == s4);
            System.out.println(s3.intern() == s3);

     在 jdk7 及以后的版本中,字符串常量池从Perm区移到Java Heap区域。

    String s = new String("1"); 创建了两个String对象,一个位于堆中即是s,一个位于常量池中,值为"1"。
    String s2 = "1"; 由于常量池中已经存在值为"1"的String对象,所以s2指向的是常量池中的String对象。

    所以s == s2 结果为false,s与s2指向的并不是同一个对象。
    String s3 = new String("1") + new String("1"); 在堆中创建了一个值为"11"的String对象即是s3。
    s3.intern();由于常量池中没有值为"11"的String对象,所以在常量池中添加对象s3的引用。
    String s4 = "11";常量池中已经存在值为"11"的String对象(这个对象实际是s3),所以s4指向了s3指向的String对象。
    所以s3 == s4 结果为true,s3与s4指向的是同一个对象,都是堆中值为 "11" 的String对象。

    其它示例:

            // 在堆中创建了一个值为"11"的String对象即是s3
            String s3 = new String("1") + new String("1");
    
            // 常量池中没有值为"11"的String对象
            // 所以在池中创建了一个新的String对象
            String s4 = "11";
    
            // 常量池中存在值为"11"的String对象,即是s4指向的对象
            // intern返回s4指向的对象
            s3.intern();
    
            // intern返回的是s4指向的对象
            System.out.println(s3.intern() == s4); // true
    
            // s3指向的是堆中的对象
            // s4指向的是常量池中新建的对象
            // 故结果为false
            System.out.println(s3 == s4);          // false
            String str1 = new String("Hello") + new String("World");
            System.out.println(str1.intern() == str1);  // true
            String str2 = "HelloWorld";
            System.out.println(str1 == str2);           // true
            String str2 = "HelloWorld";
    
            String str1 = new String("Hello") + new String("World");
            System.out.println(str1.intern() == str1);  // false
            System.out.println(str1 == str2);           // false
  • 相关阅读:
    本周面试总结
    本周面试总结
    本周面试题总结
    网络请求AJAX
    es6数组、对象的解构赋值
    es6箭头函数
    es6总结
    js限定输入为数字包括负数正则
    js限定输入为非负数,浮点数正则
    js数值千分隔(正则)
  • 原文地址:https://www.cnblogs.com/deltadeblog/p/9360909.html
Copyright © 2020-2023  润新知