intern()方法官方解释:返回字符串对象的规范化表示形式 最近在学习jvm相关的知识,学到String常量池、intern()方法时,对intern()方法产生了兴趣,但由于它本身为native方法,不能直接去看源码,官方解释和一些博客上的总结看得我一脸懵逼,搞了好久,终于通过大量例子搞懂了大致作用,特在此总结记录: 一句话解释intern()方法:一个String对象调用intern()方法后,会去String常量池中查看是否有相应的字面量,如果没有则添加相应的字面量,然后将常量池中的字面量返回。(注意:jdk1.8以后运行时常量池在堆内存中) 下面通过例子对intern()方法进行进一步的分析:[Asm] 纯文本查看 复制代码 String str1 = "a"; //这种方式会把对象放入String常量池,通常把这种对象称为字面量
String str2 = "b";
String str3 = "ab";
String str4 = "a"+"b";
String str5 = str1 + str2;
String str6 = new String("a") + new String("b");
String str7 = new String("ab");
System.out.println(str6.equals(str3)); //true
System.out.println(str6 == str3); //false
System.out.println(str6.intern() == str3); //true
System.out.println(str6.intern() == str4); //true
System.out.println(str6.intern() == str5); //false
System.out.println(str7.equals(str3)); //true
System.out.println(str7 == str3); //false
System.out.println(str7.intern() == str3); //true
System.out.println(str7.intern() == str4); //true
System.out.println(str7.intern() == str5); //false 由这些例子我们可以得到:String对象的两种创建方式中,通过引号创建对象会在String常量池中创建对象,也就是本文中的字面量,也就是官方解释中的字符串对象的规范化表示;而通过new关键字创建对象则不会在String常量池中创建对象,而是在堆中创建对象;字面量和对象虽然都在堆中,它们的值相同,但不是同一个东西(不是同一个对象),通过intern()方法我们可以获得对象相应的字面量,如果没有则会添加进去。 我们在例子中要注意:str3和str4都是创建字面量,而str5、6、7则是创建对象,原因是因为Java在编译的时候有一个预编译的功能,它会帮我们把str4中的加号去除并进行相应的拼接,但由于预编译的时候无法获取变量的值,所以它无法将str5、6像str4那样预编译,自然放不到String常量池里面;同时例子中的str5和str6其实是对一类拼接情况的概括,除了这两种情况外,用append()、concat()方法测试也能获得同样结果。 |