字符斜杠是合法常量吗_【面试秘籍】你对String的intern方法了解吗
我們先來看個例子:
public class StringTest { public static void main(String[] args) { String a = "A"; String b = new String("A"); System.out.println(a == b); // false String c = b.intern(); System.out.println(a == c); // true String d = new String("A"); System.out.println(b == d); // false System.out.println(b.intern() == d.intern()); // true }}出現上述的結果,我們需要了解下,intern的作用:
(1)? 當常量池中不存在"A"這個字符串的引用,將這個對象的引用加入常量池,返回這個對象的引用。
(2)? 當常量池中存在"A"這個字符串的引用,返回這個對象的引用。如下圖
字符串常量池
字符串常量池的位置
字符串常量池大家可以認為獨立在運行時常量池之外,不要和運行時常量池混淆。字符串常量池應該是在堆中。
字符串常量池里放的是什么
字符串常量池里放的實際上是字符串對象的引用,而不是字符串對象,這個也是十分容易混淆的地方,字符串常量池里的引用指向堆中的字符串對象,但是堆中的字符串對象,只有一部分是被字符串常量池所引用的,還有一部分,我們稱為不在常量池中,例如:
String b = new String("A");因此,常見的一些面試題,我們就有了答案:
(1)現在當有人問 String str = new String(“abc”);創建了幾個對象,常量池有abc字段是1個,常量池沒有"abc"字段則是2個。
(2)String str=“abc”;創建了幾個對象(如果常量池里面已經有對象了就是0個。如果沒有就是1個);
(3)new String(“abc”).intern();創建了幾個對象(如果常量池里面已經有該字符串對象了就是1個,如果沒有就是兩個)
了解了作用,那intern有什么用途呢?
1)使用==比較String對象
有人說,比較String用equals方法就行了,為什么使用intern后使用==來操作呢?
真的是這樣嗎,我們先看下equals方法:
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }我們發現equals方法中對字符串比較真的是暴力,直接從頭到尾挨個字符比較,如果字符串長度很大,前面字符相差不大,效率就會很低下,在性能要求很高的場景下,這種比較是不能容忍的。
那么我們在創建字符串的時候都是以intern()方法,那使用==比較就會效率高的多。
2)使用intern()方法,減少堆中創建過多的字符串對象,減少內存消耗
我們再來討論下不同版本jdk中的intern()方法:
JDK1.6 和 JDK1.7及以上 在 intern() 方法的實現上,有相同,也有不同。
相同點:都先去查看字符串常量池是否有該字符串,如果有,則返回字符串常量池中的引用。不同點:JDK1.7+,當字符串常量池中找不到對應的字符串時,不會將字符串拷貝到字符串常量池,而只是生成一個對該字符串的引用在字符串常量池。而 JDK1.6 會拷貝字符串至字符串常量池
總結
以上是生活随笔為你收集整理的字符斜杠是合法常量吗_【面试秘籍】你对String的intern方法了解吗的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓设置动态锁屏(安卓动态屏锁)
- 下一篇: 刮蹭备案后 对方没报案(刮蹭备案后)