您好,歡迎來(lái)電子發(fā)燒友網(wǎng)! ,新用戶?[免費(fèi)注冊(cè)]

您的位置:電子發(fā)燒友網(wǎng)>源碼下載>java源碼下載>

探究面試最常見(jiàn)的String、StringBuffer、StringBuilder問(wèn)題

大小:0.5 MB 人氣: 2017-09-27 需要積分:2

  一。你了解String類嗎?

  二。深入理解String、StringBuffer、StringBuilder

  三。不同場(chǎng)景下三個(gè)類的性能測(cè)試

  四。常見(jiàn)的關(guān)于String、StringBuffer的面試題(辟謠網(wǎng)上流傳的一些曲解String類的說(shuō)法)

  若有不正之處,請(qǐng)多多諒解和指正,不勝感激。

  一。你了解String類嗎?

  想要了解一個(gè)類,最好的辦法就是看這個(gè)類的實(shí)現(xiàn)源代碼,String類的實(shí)現(xiàn)在\jdk1.6.0_14\src\java\lang\String.java 文件中。

  打開(kāi)這個(gè)類文件就會(huì)發(fā)現(xiàn)String類是被final修飾的:

  public finalclassStringimplements java.io.Serializable, Comparable《String》, CharSequence { /** The value is used for character storage. */privatefinalchar value[]; /** The offset is the first index of the storage that is used. */privatefinalint offset; /** The count is the number of characters in the String. */privatefinalint count; /** Cache the hash code for the string */privateint hash; // Default to 0/** use serialVersionUID from JDK 1.0.2 for interoperability */privatestatic finallong serialVersionUID = - 6849794470754667710L; 。。.。。. }

  從上面可以看出幾點(diǎn):

  1)String類是final類,也即意味著String類不能被繼承,并且它的成員方法都默認(rèn)為final方法。在Java中,被final修飾的類是不允許被繼承的,并且該類中的成員方法都默認(rèn)為final方法。在早期的JVM實(shí)現(xiàn)版本中,被final修飾的方法會(huì)被轉(zhuǎn)為內(nèi)嵌調(diào)用以提升執(zhí)行效率。而從Java SE5/6開(kāi)始,就漸漸擯棄這種方式了。因此在現(xiàn)在的Java SE版本中,不需要考慮用final去提升方法調(diào)用效率。只有在確定不想讓該方法被覆蓋時(shí),才將方法設(shè)置為final。

  2)上面列舉出了String類中所有的成員屬性,從上面可以看出String類其實(shí)是通過(guò)char數(shù)組來(lái)保存字符串的。

  下面再繼續(xù)看String類的一些方法實(shí)現(xiàn):

  publicString substring( intbeginIndex, intendIndex) { if(beginIndex 《 0) {thrownewStringIndexOutOfBoundsException(beginIndex); } if(endIndex 》 count) {thrownewStringIndexOutOfBoundsException(endIndex); } if(beginIndex 》 endIndex) {thrownewStringIndexOutOfBoundsException(endIndex - beginIndex); } return((beginIndex == 0) && (endIndex == count)) ? this: newString(offset + beginIndex, endIndex - beginIndex, value); } publicString concat(String str) { intotherLen = str.length(); if(otherLen == 0) { returnthis; } charbuf[] = newchar[ count+ otherLen]; getChars( 0, count, buf, 0);str.getChars( 0, otherLen, buf, count); returnnewString( 0, count+ otherLen, buf); }publicString replace( charoldChar, charnewChar) { if(oldChar != newChar) { intlen = count;inti = - 1; char[] val = value; /* avoid getfield opcode */intoff = offset; /* avoid getfield opcode */while(++i 《 len) { if(val[off + i] == oldChar) { break; } } if(i 《 len) { charbuf[] =newchar[len]; for( intj = 0; j 《 i ; j++) { buf[j] = val[off+j]; } while(i 《 len) { charc = val[off + i]; buf[i] = (c == oldChar) ? newChar : c; i++; } returnnewString( 0, len, buf); } } returnthis;

  從上面的三個(gè)方法可以看出,無(wú)論是sub操、concat還是replace操作都不是在原有的字符串上進(jìn)行的,而是重新生成了一個(gè)新的字符串對(duì)象。也就是說(shuō)進(jìn)行這些操作后,最原始的字符串并沒(méi)有被改變。

  在這里要永遠(yuǎn)記住一點(diǎn):

  “對(duì)String對(duì)象的任何改變都不影響到原對(duì)象,相關(guān)的任何change操作都會(huì)生成新的對(duì)象”。

  在了解了于String類基礎(chǔ)的知識(shí)后,下面來(lái)看一些在平常使用中容易忽略和混淆的地方。

  二。深入理解String、StringBuffer、StringBuilder

  1.String str=”hello world”和String str=new String(“hello world”)的區(qū)別

  想必大家對(duì)上面2個(gè)語(yǔ)句都不陌生,在平時(shí)寫代碼的過(guò)程中也經(jīng)常遇到,那么它們到底有什么區(qū)別和聯(lián)系呢?下面先看幾個(gè)例子:

  publicclassMain { publicstaticvoidmain(String[] args) { String str1 = “hello world”; String str2 = newString( “hello world”); String str3 = “hello world”; String str4 = newString( “hello world”); System. out.println(str1==str2); System. out.println(str1==str3); System.out.println(str2==str4); } }

  這段代碼的輸出結(jié)果為

  探究面試最常見(jiàn)的String、StringBuffer、StringBuilder問(wèn)題

  為什么會(huì)出現(xiàn)這樣的結(jié)果?下面解釋一下原因:

  在前面一篇講解關(guān)于JVM內(nèi)存機(jī)制的一篇博文中提到 ,在class文件中有一部分 來(lái)存儲(chǔ)編譯期間生成的 字面常量以及符號(hào)引用,這部分叫做class文件常量池,在運(yùn)行期間對(duì)應(yīng)著方法區(qū)的運(yùn)行時(shí)常量池。

  因此在上述代碼中,String str1 = “hello world”;和String str3 = “hello world”; 都在編譯期間生成了 字面常量和符號(hào)引用,運(yùn)行期間字面常量”hello world”被存儲(chǔ)在運(yùn)行時(shí)常量池(當(dāng)然只保存了一份)。通過(guò)這種方式來(lái)將String對(duì)象跟引用綁定的話,JVM執(zhí)行引擎會(huì)先在運(yùn)行時(shí)常量池查找是否存在相同的字面常量,如果存在,則直接將引用指向已經(jīng)存在的字面常量;否則在運(yùn)行時(shí)常量池開(kāi)辟一個(gè)空間來(lái)存儲(chǔ)該字面常量,并將引用指向該字面常量。

  眾所周知,通過(guò)new關(guān)鍵字來(lái)生成對(duì)象是在堆區(qū)進(jìn)行的,而在堆區(qū)進(jìn)行對(duì)象生成的過(guò)程是不會(huì)去檢測(cè)該對(duì)象是否已經(jīng)存在的。因此通過(guò)new來(lái)創(chuàng)建對(duì)象,創(chuàng)建出的一定是不同的對(duì)象,即使字符串的內(nèi)容是相同的。

  2.String、StringBuffer以及StringBuilder的區(qū)別

  既然在Java中已經(jīng)存在了String類,那為什么還需要StringBuilder和StringBuffer類呢?

非常好我支持^.^

(0) 0%

不好我反對(duì)

(0) 0%

      發(fā)表評(píng)論

      用戶評(píng)論
      評(píng)價(jià):好評(píng)中評(píng)差評(píng)

      發(fā)表評(píng)論,獲取積分! 請(qǐng)遵守相關(guān)規(guī)定!

      ?