成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

面試別再問我String了

leon / 1012人閱讀

摘要:閱讀原文面試別再問我了字符串廣泛應(yīng)用在編程中,在中字符串屬于對象,提供了類來創(chuàng)建和操作字符串。測試此字符串是否以指定的后綴結(jié)束。當(dāng)執(zhí)行此句時,因為對應(yīng)的實例已經(jīng)存在于字符串常量池中,所以會將此實例復(fù)制到會在堆中并返回引用地址。

閱讀原文:面試別再問我String了

字符串廣泛應(yīng)用 在Java 編程中,在 Java 中字符串屬于對象,Java 提供了 String 類來創(chuàng)建和操作字符串。

String 簡介

String定義:

public final class String
    implements java.io.Serializable, Comparable, CharSequence {}
為什么設(shè)計為不可變類呢?
String設(shè)計為不可變類主要考慮到:效率和安全。

效率:1.在早期的JVM實現(xiàn)版本中,被final修飾的方法會被轉(zhuǎn)為內(nèi)嵌調(diào)用以提升執(zhí)行效率。而從Java SE5/6開始,就漸漸擯棄這種方式了。因此在現(xiàn)在的Java SE版本中,不需要考慮用final去提升方法調(diào)用效率。只有在確定不想讓該方法被覆蓋時,才將方法設(shè)置為final。2.緩存hashcode,String不可變,所以hashcode不變,這樣緩存才有意義,不必重新計算。

安全:String常被作為網(wǎng)絡(luò)連接,文件操作等參數(shù)類型,倘若可改變,會出現(xiàn)意想不到的結(jié)果。

測試掌握程度

為了不浪費(fèi)你的時間,請看下面的題目,若你一目了然,可以跳過本文了。

public class Test {
    public static void main(String[] args) {
        String str1 = "HelloFlyapi";
        String str2 = "HelloFlyapi";
        String str3 = new String("HelloFlyapi");
        String str4 = "Hello";
        String str5 = "Flyapi";
        String str6 = "Hello" + "Flyapi";
        String str7 = str4 + str5;

        System.out.println("str1 == str2 result: " + (str1 == str2));

        System.out.println("str1 == str3 result: " + (str1 == str3));

        System.out.println("str1 == str6 result: " + (str1 == str6));

        System.out.println("str1 == str7 result: " + (str1 == str7));

        System.out.println("str1 == str7.intern() result: " + (str1 == str7.intern()));

        System.out.println("str3 == str3.intern() result: " + (str3 == str3.intern()));
    }
}

String 的創(chuàng)建方式

從上面的題中你會知道,String的創(chuàng)建方式有兩種:

直接賦值

此方式在方法區(qū)中字符串常量池中創(chuàng)建對象

String str = "flyapi";

構(gòu)造器

此方式在堆內(nèi)存創(chuàng)建對象

String str = new String();

分析

要理解String,那么要了解JVM內(nèi)存中的棧(stack)、堆(heap)和方法區(qū)。簡要圖如下:

str1 == str2

String str1 = "HelloFlyapi";
String str2 = "HelloFlyapi";

System.out.println(str1 == str2); // true

當(dāng)執(zhí)行第一句時,JVM會先去常量池中查找是否存在HelloFlyapi,當(dāng)存在時直接返回常量池里的引用;當(dāng)不存在時,會在字符創(chuàng)常量池中創(chuàng)建一個對象并返回引用。

當(dāng)執(zhí)行第二句時,同樣的道理,由于第一句已經(jīng)在常量池中創(chuàng)建了,所以直接返回上句創(chuàng)建的對象的引用。

str1 == str3

String str1 = "HelloFlyapi";
String str3 = new String("HelloFlyapi");

System.out.println(str1 == str3); // false

執(zhí)行第一句,同上第一句。

執(zhí)行第二句時,會在堆(heap)中創(chuàng)建一個對象,當(dāng)字符創(chuàng)常量池中沒有‘HelloFlyapi’時,會在常量池中也創(chuàng)建一個對象;當(dāng)常量池中已經(jīng)存在了,就不會創(chuàng)建新的了。

str1 == str6

String str1 = "HelloFlyapi";
String str6 = "Hello" + "Flyapi";

System.out.println(str1 == str6); // true

由于"Hello"和"Flyapi"都是常量,編譯時,第二句會被自動編譯為‘String str6 = "HelloFlyapi";’

str1 == str7

String str1 = "HelloFlyapi";
String str4 = "Hello";
String str5 = "Flyapi";
String str7 = str4 + str5;

System.out.println(str1 == str7); // false

其中前三句變量存儲的是常量池中的引用地址。

第四句執(zhí)行時,JVM會在堆(heap)中創(chuàng)建一個以str4為基礎(chǔ)的一個StringBuilder對象,然后調(diào)用StringBuilder的append()方法完成與str5的合并,之后會調(diào)用toString()方法在堆(heap)中創(chuàng)建一個String對象,并把這個String對象的引用賦給str7。

常用方法

下面是 String 類支持的方法,更多詳細(xì),參看 Java String API 文檔:

方法 描述
char charAt(int index) 返回指定索引處的 char 值。
int compareTo(Object o) 把這個字符串和另一個對象比較。
int compareTo(String anotherString) 按字典順序比較兩個字符串。
boolean endsWith(String suffix) 測試此字符串是否以指定的后綴結(jié)束。
boolean equals(Object anObject) 將此字符串與指定的對象比較。
boolean equalsIgnoreCase(String anotherString) 將此 String 與另一個 String 比較,不考慮大小寫。
byte[] getBytes() 使用平臺的默認(rèn)字符集將此 String 編碼為 byte 序列,并將結(jié)果存儲到一個新的 byte 數(shù)組中。
byte[] getBytes(String charsetName) 使用指定的字符集將此 String 編碼為 byte 序列,并將結(jié)果存儲到一個新的 byte 數(shù)組中。
int indexOf(int ch) 返回指定字符在此字符串中第一次出現(xiàn)處的索引。
int indexOf(int ch, int fromIndex) 返回在此字符串中第一次出現(xiàn)指定字符處的索引,從指定的索引開始搜索。
int indexOf(String str) 返回指定子字符串在此字符串中第一次出現(xiàn)處的索引。
int indexOf(String str, int fromIndex) 返回指定子字符串在此字符串中第一次出現(xiàn)處的索引,從指定的索引開始。
String intern() 返回字符串對象的規(guī)范化表示形式。
int lastIndexOf(int ch) 返回指定字符在此字符串中最后一次出現(xiàn)處的索引。
int lastIndexOf(int ch, int fromIndex) 返回指定字符在此字符串中最后一次出現(xiàn)處的索引,從指定的索引處開始進(jìn)行反向搜索。
int lastIndexOf(String str) 返回指定子字符串在此字符串中最右邊出現(xiàn)處的索引。
int lastIndexOf(String str, int fromIndex) 返回指定子字符串在此字符串中最后一次出現(xiàn)處的索引,從指定的索引開始反向搜索。
int length() 返回此字符串的長度。
boolean matches(String regex) 告知此字符串是否匹配給定的正則表達(dá)式。
String replace(char oldChar, char newChar) 返回一個新的字符串,它是通過用 newChar 替換此字符串中出現(xiàn)的所有 oldChar 得到的。
String replaceAll(String regex, String replacement) 使用給定的 replacement 替換此字符串所有匹配給定的正則表達(dá)式的子字符串。
String replaceFirst(String regex, String replacement) 使用給定的 replacement 替換此字符串匹配給定的正則表達(dá)式的第一個子字符串。
String[] split(String regex) 根據(jù)給定正則表達(dá)式的匹配拆分此字符串。
String[] split(String regex, int limit) 根據(jù)匹配給定的正則表達(dá)式來拆分此字符串。
boolean startsWith(String prefix) 測試此字符串是否以指定的前綴開始。
boolean startsWith(String prefix, int toffset) 測試此字符串從指定索引開始的子字符串是否以指定前綴開始。
String substring(int beginIndex) 返回一個新的字符串,它是此字符串的一個子字符串。
String substring(int beginIndex, int endIndex) 返回一個新字符串,它是此字符串的一個子字符串。
char[] toCharArray() 將此字符串轉(zhuǎn)換為一個新的字符數(shù)組。
String toLowerCase() 使用默認(rèn)語言環(huán)境的規(guī)則將此 String 中的所有字符都轉(zhuǎn)換為小寫。
String toUpperCase() 使用默認(rèn)語言環(huán)境的規(guī)則將此 String 中的所有字符都轉(zhuǎn)換為大寫。
String trim() 返回字符串的副本,忽略前導(dǎo)空白和尾部空白。
String相關(guān)

由于String的不可變性導(dǎo)致,字符串變更時效率低下,在之后得JDK版本中出現(xiàn)了StringBuilder和StringBuffer.

可變性 線程安全
String 不可變 安全
StringBuffer 可變 安全
StringBuilder 可變 非安全

使用選擇

當(dāng)有少量連接操作時,使用String

當(dāng)單線程下有大量連接操作時,使用StringBuilder

當(dāng)多線程下有大量連接操作時,使用StringBuffer

常見String面試題

String str = new String("abc")創(chuàng)建了多少個實例?

這個問題其實是不嚴(yán)謹(jǐn)?shù)?,但面試一般會遇到,所以我們要補(bǔ)充來說明。

類的加載和執(zhí)行要分開來講:
創(chuàng)建了兩個

當(dāng)加載類時,"abc"被創(chuàng)建并駐留在了字符創(chuàng)常量池中(如果先前加載中沒有創(chuàng)建駐留過)。

當(dāng)執(zhí)行此句時,因為"abc"對應(yīng)的String實例已經(jīng)存在于字符串常量池中,所以JVM會將此實例復(fù)制到會在堆(heap)中并返回引用地址。

通過字節(jié)碼我們可以看到:

源碼:String str = new String("abc")

字節(jié)碼:

    Code:
       0: new           #2                  // class java/lang/String
       3: dup
       4: ldc           #3                  // String abc
       6: invokespecial #4                  // Method java/lang/String."":(Ljava/lang/String;)
       9: astore_1
      10: return

執(zhí)行時僅(#2)創(chuàng)建了一個對象。

關(guān)于這個面試題,可以看看一個超大牛的回答:http://rednaxelafx.iteye.com/...

本文優(yōu)先發(fā)布于微信公眾號:碼上實戰(zhàn) 和 GitHub 上。

GitHub flyhero

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/73991.html

相關(guān)文章

  • 面試被問爛的 Spring IOC(求求你再問)

    摘要:例如資源的獲取,支持多種消息例如的支持,對多了工具級別的支持等待。最上面的知道吧我就不講了。生命周期事件回調(diào)等。他支持不同信息源頭,支持工具類,支持層級容器,支持訪問文件資源,支持事件發(fā)布通知,支持接口回調(diào)等等。 廣義的 IOC IoC(Inversion of Control) 控制反轉(zhuǎn),即不用打電話過來,我們會打給你。 兩種實現(xiàn): 依賴查找(DL)和依賴注入(DI)。 IOC 和...

    denson 評論0 收藏0
  • 小而有料的final

    摘要:閱讀原文小而有料的想聽文章核心內(nèi)容語音對話版,請到微信公眾號碼上實戰(zhàn),閱讀原文這塊肉雖然小,但不可不知,因為不僅面試可能會問,實際中也常使用。參考書籍編程思想深入理解虛擬機(jī)更多精彩技術(shù)文章盡在微信公眾號碼上實戰(zhàn) 閱讀原文:小而有料的final(想聽文章核心內(nèi)容語音對話版,請到微信公眾號——碼上實戰(zhàn),閱讀原文) final這塊肉雖然小,但不可不知,因為不僅面試可能會問,實際中也常使用。就...

    Baoyuan 評論0 收藏0
  • 不要再問我this的指向問題

    摘要:所以構(gòu)造函數(shù)里的指的就是將要被出來的新對象。希望看完這篇文章之后,再有人問指向的問題,你可以嘴角微微上揚(yáng),冷笑一聲不要再問我的指向問題了。 this的指向已經(jīng)是一個老生常談的問題,每逢面試都要去復(fù)習(xí)復(fù)習(xí),近來鞏固js的基礎(chǔ),決心徹底掌握這個知識點(diǎn),一勞永逸。說明一下,為了不影響大家的思考過程,下面的代碼都不會去注釋答案,想知道答案,只需要去控制臺執(zhí)行一下。 四類場景逐一擊破 首先,分析...

    nifhlheimr 評論0 收藏0
  • 拜托!面試請不要再問我Spring Cloud底層原理!

    摘要:不過大多數(shù)講解還停留在對功能使用的層面,其底層的很多原理,很多人可能并不知曉。每個線程池里的線程就僅僅用于請求那個服務(wù)。 歡迎關(guān)注微信公眾號:石杉的架構(gòu)筆記(id:shishan100) 每日更新!精品技術(shù)文章準(zhǔn)時送上! 目錄 一、業(yè)務(wù)場景介紹 二、Spring Cloud核心組件:Eureka 三、Spring Cloud核心組件:Feign 四、Spring Cloud核心組件:R...

    wums 評論0 收藏0
  • 拜托!面試請不要再問我Spring Cloud底層原理!

    摘要:不過大多數(shù)講解還停留在對功能使用的層面,其底層的很多原理,很多人可能并不知曉。每個線程池里的線程就僅僅用于請求那個服務(wù)。 歡迎關(guān)注微信公眾號:石杉的架構(gòu)筆記(id:shishan100) 每日更新!精品技術(shù)文章準(zhǔn)時送上! 目錄 一、業(yè)務(wù)場景介紹 二、Spring Cloud核心組件:Eureka 三、Spring Cloud核心組件:Feign 四、Spring Cloud核心組件:R...

    wangjuntytl 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<