深入理解java虚拟机(三):String.intern()-字符串常量池

 2019-12-22 10:59  阅读(853)
文章分类:JVM

看源码:

public native String intern();

Returns a canonical representation for the string object.

A pool of strings, initially empty, is maintained privately by the class String.

When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.

It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true.

All literal strings and string-valued constant expressions are interned. String literals are defined in §3.10.5 of the Java Language Specification

Returns:
a string that has the same contents as this string, but is guaranteed to be from a pool of unique strings.

意思是说当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用

看下面这段代码:

[java]
view plain
copy
print
?
2019120001455\_1.png
2019120001455\_2.png

  1. **public****class** StringInternTest {
  2. public**static**void main(String[] args) {
  3. String str1 = new StringBuilder(“chaofan”).append(“wei”).toString();
  4. System.out.println(str1.intern() == str1);
  5. String str2 = new StringBuilder(“ja”).append(“va”).toString();
  6. System.out.println(str2.intern() == str2);
  7. }
  8. }

2019120001455\_3.png

有图可知,当在jdk1.6中运行时,会得到两个false,而在jdk1.7中运行,会得到一个true和一个false。
产生的差异在于在jdk1.6中 intern 方法会把首次遇到的字符串实例复制到永久待(常量池)中,并返回此引用;但在jdk1.7中,只是会把首次遇到的字符串实例的引用添加到常量池中(没有复制),并返回此引用
所以在jdk1.7中执行上面代码,str1返回true是引用他们指向的都是str1对象(堆中)(池中不存在,返回原引用),而str2返回false是因为池中已经存在”java”了(关键词),所以返回的池的对象,因此不相等。

看下面实例:

[java]
view plain
copy
print
?
2019120001455\_4.png
2019120001455\_5.png

  1. @Test
  2. **public****void** test3(){
  3. String str1 = “a”;
  4. String str2 = “b”;
  5. String str3 = “ab”;
  6. String str4 = str1 + str2;
  7. String str5 = new String(“ab”);
  8. System.out.println(str5.equals(str3));//true
  9. System.out.println(str5 == str3);//false
  10. System.out.println(str5.intern() == str3);//true
  11. System.out.println(str5.intern() == str4);//false
  12. }
  13. @Test
  14. **public****void** test4(){
  15. String a = new String(“ab”);
  16. String b = new String(“ab”);
  17. String c = “ab”;
  18. String d = “a” + “b”;
  19. String e = “b”;
  20. String f = “a” + e;
  21. System.out.println(b.intern() == a);//fasle
  22. System.out.println(b.intern() == c);//true
  23. System.out.println(b.intern() == d);//true 编译期d已确定(修改、赋值)为ab
  24. System.out.println(b.intern() == f);//false
  25. System.out.println(b.intern() == a.intern());//true
  26. }
  27. @Test
  28. **public****void** test5(){
  29. // 编译期已确定
  30. String a = “abc”;
  31. String b = “abc”;
  32. &sp; String c = “a” + “b” + “c”;
  33. String d = “a” + “bc”;
  34. String e = “ab” + “c”;
  35. System.out.println(a == b);//true
  36. System.out.println(a == c);//true
  37. System.out.println(a == d);//true
  38. System.out.println(a == e);//true
  39. System.out.println(c == d);//true
  40. System.out.println(c == e);//true
  41. }
点赞(1)
版权归原创作者所有,任何形式转载请联系作者; Java 技术驿站 >> 深入理解java虚拟机(三):String.intern()-字符串常量池

相关推荐