Java 中 String 的字面量与 intern 方法

下方代码主要说明:

String b = new String("xyz")  创建2个对象,一个在常量池中的 "xyz",一个 String 实例对象,返回的是实例对象引用。

intern() 方法有两个作用,一是取出 String Pool 中的值(可能是字面量可能是引用),二是如果 String Pool 没有该值,则将String 对象引用添加到 String Pool

String a = "abc"  该表达式有两个作用,一是取出 String Pool 中的值并返回(可能是字面量可能是对象的引用),二是如果 String Pool 没有该值,则将 字面量添加到 String Pool

检测代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class Test {
 
    @org.junit.Test
    public void test() {
 
 
        String s1 = new String("x") + new String("yz");
                                             //这里的 new String 会创建5个对象,3个实例,2个字面量,存入 "x", "yz" 2 个字面量。
                                             //返回 "xyz" 的引用
        String l_s1 = s1.intern();           //当常量池中没有该字面量或引用时,则把该字符串对象的引用添加到常量池中,并返回引用
        String s2 = "xyz";
 
        printHash(l_s1);                     //引用
        printHash(s1);                       //引用
        printHash(s2);                       //当常量中有该字符串的引用,返回引用
 
 
        String s3 = new String("abc"); //生成 2个对象,1个实例,1个 "abc" 字面量。存入 "abc" 字面量,返回 "abc" 引用
        String s4 = "abc";
        String l_s3 = s3.intern();            //与前面对比,可知常量池中确实有该字符串,返回的是字面量
 
        printHash(l_s3);                      //字面量
        printHash(s3);                        //引用
        printHash(s4);                        //字面量
 
 
        String s = "s";                       //存入该字面量,返回该字面量
        printHash(s.intern());                //字面量
        printHash(s);                         //字面量
    }
 
    private void printHash(String str) {
        int hash = System.identityHashCode(str);
        System.out.println(str.hashCode() + " : " + hash);
    }
 
}

返回结果:

1
2
3
4
5
6
7
8
119193 : 476800120
119193 : 476800120
119193 : 476800120
96354 : 1744347043
96354 : 1254526270
96354 : 1744347043
115 : 662441761
115 : 662441761

 

下方代码说明:

new String("xyz") 会生成 2 个对象,而 new String(bytes) 只生成一个对象

检测代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class Test {
 
    @org.junit.Test
    public void test() {
        char[] bytes = new char[]{'a', 'b', 'c'};
        String s1 = new String(bytes);
        String l_s1 = s1.intern();
        String s2 = "abc";
        printHash(s1);
        printHash(l_s1);
        printHash(s2);
 
        String s3 = new String("xyz");
        String l_s3 = s3.intern();
        String s4 = "abc";
        printHash(s3);
        printHash(l_s3);
        printHash(s4);
    }
 
    private void printHash(String str) {
        int hash = System.identityHashCode(str);
        System.out.println(str.hashCode() + " : " + hash);
    }
 
}

返回结果

1
2
3
4
5
6
96354 : 476800120
96354 : 476800120
96354 : 476800120
119193 : 1744347043
119193 : 1254526270
96354 : 476800120

 

总结:

在不同情况下 new String(param) 方法或 "abc" 会生成字面量与引用。那么考虑一般情况,在使用 new String("abc") 或 String s = "abc" ,通常会生成字面量。使用 new String(bytes) 通常不会自动生成字面量,需要调用 new String(bytes).intern()  方法。

 补充:

 

1. 对象的 hashCode 方法与 System.identityHashCode 区别 :一般情况下 hashCode 等同于 identityHashCode。但是由于下一条中的因素,会导致不相等。

2. 当对象的 equals 方法重写时,也需要正确重写对象的 hashCode 方法。一个原则是,equals 相等,hashCode 必须相等。而 hashCode 相同,equals 可以不相等。在该对象作为字典中的 key 涉及到 Hash 存取时,判断是否相等先使用 hashCode  判断,再使用 equals 判断,这样可以提高效率。(分析见 参考

 


 jdk6 的比较请参考

 

posted on   Lemo_wd  阅读(546)  评论(0编辑  收藏  举报

编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示