String s = new String("java"); 只創(chuàng)建了一個對象!好好看好好學(xué),要了解原理!
public?static?void?main(String[]?args)?{
????String?str1?=?new?StringBuilder("計(jì)算機(jī)").append("軟件").toString();
????System.out.println(str1.intern()?==?str1);
????String?str2?=?new?StringBuilder("ja").append("va").toString();
????System.out.println(str2.intern()?==?str2);
}
這個題目是在《深入理解Java虛擬機(jī):JVM高級特性與實(shí)戰(zhàn)(第3版)》看到的,按理說這兩個結(jié)果不應(yīng)該一樣嗎?為什么會出這種題呢?


作者想告訴我,一次不信,兩次你應(yīng)該信了吧!機(jī)智如我。為了證明我如此機(jī)智,我特地的試了一下。


為什么?為什么?為什么?你要離開我!(不好意思串臺了)。為什么是true和flase。

吧啦吧啦吧啦說了一大堆,意思就是想讓讀者知道,字符串常量池jdk1.6和jdk1.7及以上存放的位置變啦,以前放到永久代的,以后就放在java堆上了。jdk1.6的intern()的方法首次遇到會把字符串復(fù)制一份到有永久代,而jdk1.7及以上的只需要在常量池里記錄一下首次出現(xiàn)的實(shí)例引用。"只需要在常量池里記錄一下首次出現(xiàn)的實(shí)例引用"說白了就是常量池記錄第一次出現(xiàn)這個字符串的地址。其實(shí)我這地方有個好奇,那不就是這個對象永久不會被垃圾收集器收集了嘛?當(dāng)然我也不敢問。。。
既然都說到這了,那就一起看看intern()方法吧!(jdk1.8)

/**
????*?Returns?a?canonical?representation?for?the?string?object.
????*?
????*?A?pool?of?strings,?initially?empty,?is?maintained?privately?by?the
????*?class?{@code?String}.
????*?
????*?When?the?intern?method?is?invoked,?if?the?pool?already?contains?a
????*?string?equal?to?this?{@code?String}?object?as?determined?by
????*?the?{@link?#equals(Object)}?method,?then?the?string?from?the?pool?is
????*?returned.?Otherwise,?this?{@code?String}?object?is?added?to?the
????*?pool?and?a?reference?to?this?{@code?String}?object?is?returned.
????*?
????*?It?follows?that?for?any?two?strings?{@code?s}?and?{@code?t},
????*?{@code?s.intern()?==?t.intern()}?is?{@code?true}
????*?if?and?only?if?{@code?s.equals(t)}?is?{@code?true}.
????*?
????*?All?literal?strings?and?string-valued?constant?expressions?are
????*?interned.?String?literals?are?defined?in?section?3.10.5?of?the
????*?The?Java™?Language?Specification.
????*
????*?@return??a?string?that?has?the?same?contents?as?this?string,?but?is
????*??????????guaranteed?to?be?from?a?pool?of?unique?strings.
????*/
public?native?String?intern();
原諒我看不懂,所以谷歌翻譯了下。其實(shí)意思就是調(diào)用intern方法時,如果池中已經(jīng)包含一個等于此對象的字符串,此方法,則從池中取出字符串返回。否則,此對象地址將添加到池,并返回對此對象的引用。 額,和上面一個意思。
嘰嘰歪歪說了半天,我知道第一個是true,我是問你第二個為什么是false,光說屁話。

老爺們別生氣,我這就慢慢給你道來。其實(shí)我也不知道。然后在知乎看到一片文章《如何理解《深入理解java虛擬機(jī)》第二版中對String.intern()方法的講解中所舉的例子?》,呵呵噠,原來在初始化的時候已經(jīng)把java這個字符串放到常量池中了。

你說這不巧了嗎?

舉個例子讓我懷疑了人生,哎。。。
哎,別先,如果我發(fā)現(xiàn)了一個面試題,String s = new String("s")證明他是創(chuàng)建兩個對象的了,哈哈哈哈。。。

public?static?void?main(String[]?args)?{
????String?s?=?new?String("s");
????System.out.println(s.intern()?==?s);
}
結(jié)果是false,那不就是創(chuàng)建了兩個對象嗎?第一個是new String("s"),第二個是常量池的s。哈哈哈哈。
小編小編,那你怎么證明java啟動的時候常量池里面沒有s呢?畢竟java這個字符串一開始也存在常量池??!
額。。。

我又想到一個有意思的問題,String s = new String("java")創(chuàng)建了幾個對象,哈哈哈哈,它創(chuàng)建了一個對象,這次沒人反駁我了把。哈哈哈哈~
