84669 Lernen von Personen
152542 Lernen von Personen
20005 Lernen von Personen
5487 Lernen von Personen
7821 Lernen von Personen
359900 Lernen von Personen
3350 Lernen von Personen
180660 Lernen von Personen
48569 Lernen von Personen
18603 Lernen von Personen
40936 Lernen von Personen
1549 Lernen von Personen
1183 Lernen von Personen
32909 Lernen von Personen
欢迎选择我的课程,让我们一起见证您的进步~~
上面的代码, 我用 JDK6 和 JDK7 分别运行了一下, 结果如下:
JDK6: false, false JDK7: false, false
没有如题主所说的是 true, false. 我想究其原因, 主要有两点:
字符串 "java" 比较特殊, 它在常量池中固定存在的
因此代码
String str1 = new StringBuilder("ja").append("va").toString(); System.out.println(str1.intern() == str1);
str1.intern() 返回的是常量池中的对象, 于是和堆上的 str1 就不是同一个对象了.
"python" 字符串已经在代码中出现了, 因此会添加到常量池中.
第二部分的代码中, 因为出现了字面常量 "python", 因此它会添加到常量池中.而:
String str2 = new StringBuilder("python").append("").toString(); System.out.println(str2.intern() == str2);
为字符串 "python" 添加了空字符串 "", 因此相当于没有添加新的字符串常量, 进而 str2.intern() 返回的还是常量池中的对象.
其实上面的题目可以引申一下, 例如:
// 1 String str1 = new StringBuilder("ja").append("va1").toString(); System.out.println(str1.intern() == str1); // true // 2 String str2 = new StringBuilder("python").append("").toString(); System.out.println(str2.intern() == str2); // false
我仅仅把第一部分的代码 "StringBuilder("ja").append("va")" 改为 "StringBuilder("ja").append("va1")". 这样改动会有什么不同的结果吗?我们来看看在 JDK6 和 JDK7 下运行的结果吧:
JDK6: false, false JDK7: true, false
为什么 JDK6 和 JDK7 的运行结果不一样呢?其实这涉及到了不同的 JDK 对 intern() 方法的不同实现:在 JDK6 及以前的 JDK 中:
intern() 方法会把首次遇到的字符串实例 **复制** 到永久代中, 然后返回永久代中的实例.
而对于 JDK7 以及之上的JDK:
当遇到第一次出现的字符串时, intern() **不再复制实例**, 而是在常量池中记录首次出现的实例的引用, 并且 intern() 返回的是此实例引用.
根据 JDK6 和 JDK7 的 intern() 方法的区别, 我们就知道了例子:
在不同的 JDK 返回不同结果的原因了:在 JDK6 中, "java1" 是第一次出现的字符串常量, 因此会被复制到常量池中, intern() 方法返回的是常量池中的对象, 因此与堆上的 str1 就不等了.而在 JDK7 中, "java1" 是第一次出现的字符串常量, 但是 intern() 方法仅仅是将这个对象的引用添加到常量池中, 并没有和 JDK6 一样拷贝一个新对象到常量池, 因此 intern() 方法返回的引用其实还是和原来的 str1 相等.
上面的代码, 我用 JDK6 和 JDK7 分别运行了一下, 结果如下:
没有如题主所说的是 true, false. 我想究其原因, 主要有两点:
字符串 "java" 比较特殊, 它在常量池中固定存在的
因此代码
str1.intern() 返回的是常量池中的对象, 于是和堆上的 str1 就不是同一个对象了.
"python" 字符串已经在代码中出现了, 因此会添加到常量池中.
第二部分的代码中, 因为出现了字面常量 "python", 因此它会添加到常量池中.
而:
为字符串 "python" 添加了空字符串 "", 因此相当于没有添加新的字符串常量, 进而 str2.intern() 返回的还是常量池中的对象.
其实上面的题目可以引申一下, 例如:
我仅仅把第一部分的代码 "StringBuilder("ja").append("va")" 改为 "StringBuilder("ja").append("va1")". 这样改动会有什么不同的结果吗?
我们来看看在 JDK6 和 JDK7 下运行的结果吧:
为什么 JDK6 和 JDK7 的运行结果不一样呢?
其实这涉及到了不同的 JDK 对 intern() 方法的不同实现:
在 JDK6 及以前的 JDK 中:
而对于 JDK7 以及之上的JDK:
根据 JDK6 和 JDK7 的 intern() 方法的区别, 我们就知道了例子:
在不同的 JDK 返回不同结果的原因了:
在 JDK6 中, "java1" 是第一次出现的字符串常量, 因此会被复制到常量池中, intern() 方法返回的是常量池中的对象, 因此与堆上的 str1 就不等了.
而在 JDK7 中, "java1" 是第一次出现的字符串常量, 但是 intern() 方法仅仅是将这个对象的引用添加到常量池中, 并没有和 JDK6 一样拷贝一个新对象到常量池, 因此 intern() 方法返回的引用其实还是和原来的 str1 相等.