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

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

探究面試最常見的String、StringBuffer、StringBuilder問題

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

  一。你了解String類嗎?

  二。深入理解String、StringBuffer、StringBuilder

  三。不同場景下三個類的性能測試

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

  若有不正之處,請多多諒解和指正,不勝感激。

  一。你了解String類嗎?

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

  打開這個類文件就會發(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修飾的方法會被轉(zhuǎn)為內(nèi)嵌調(diào)用以提升執(zhí)行效率。而從Java SE5/6開始,就漸漸擯棄這種方式了。因此在現(xiàn)在的Java SE版本中,不需要考慮用final去提升方法調(diào)用效率。只有在確定不想讓該方法被覆蓋時,才將方法設(shè)置為final。

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

  下面再繼續(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;

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

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

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

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

  二。深入理解String、StringBuffer、StringBuilder

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

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

  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é)果為

  探究面試最常見的String、StringBuffer、StringBuilder問題

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

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

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

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

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

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

非常好我支持^.^

(0) 0%

不好我反對

(0) 0%

      發(fā)表評論

      用戶評論
      評價:好評中評差評

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

      ?