日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

string转为char数组_StringBuilder的区别是什么?String是不可变?一点课堂(多岸学院)...

發布時間:2025/3/8 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 string转为char数组_StringBuilder的区别是什么?String是不可变?一点课堂(多岸学院)... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

String和StringBuffer、StringBuilder的區別

可變性

簡單的來說:String 類中使用 final 關鍵字字符數組保存字符串,private final char value[],所以 String 對象是不可變的。而StringBuilder 與 StringBuffer 都繼承自 AbstractStringBuilder 類,在 AbstractStringBuilder 中也是使用字符數組保存字符串char[]value 但是沒有用 final 關鍵字修飾,所以這兩種對象都是可變的。

StringBuilder 與 StringBuffer 的構造方法都是調用父類構造方法也就是 AbstractStringBuilder 實現的,大家可以自行查閱源碼。

AbstractStringBuilder.java

abstract class AbstractStringBuilder implements Appendable, CharSequence { char[] value; int count; AbstractStringBuilder() { } AbstractStringBuilder(int capacity) { value = new char[capacity]; }

線程安全性

String 中的對象是不可變的,也就可以理解為常量,線程安全。AbstractStringBuilder 是 StringBuilder 與 StringBuffer 的公共父類,定義了一些字符串的基本操作,如 expandCapacity、append、insert、indexOf 等公共方法。StringBuffer 對方法加了同步鎖或者對調用的方法加了同步鎖,所以是線程安全的。StringBuilder 并沒有對方法進行加同步鎖,所以是非線程安全的。

性能

每次對 String 類型進行改變的時候,都會生成一個新的 String 對象,然后將指針指向新的 String 對象。StringBuffer 每次都會對 StringBuffer 對象本身進行操作,而不是生成新的對象并改變對象引用。相同情況下使用 StirngBuilder 相比使用 StringBuffer 僅能獲得 10%~15% 左右的性能提升,但卻要冒多線程不安全的風險。

對于三者使用的總結:

  • 操作少量的數據 = String
  • 單線程操作字符串緩沖區下操作大量數據 = StringBuilder
  • 多線程操作字符串緩沖區下操作大量數據 = StringBuffer
  • String為什么是不可變的嗎?

    簡單來說就是String類利用了final修飾的char類型數組存儲字符,源碼如下圖所以:

    /** The value is used for character storage. */ private final char value[];

    String真的是不可變的嗎?

    我覺得如果別人問這個問題的話,回答不可變就可以了。下面只是給大家看兩個有代表性的例子:

    1) String不可變但不代表引用不可以變

    String str = "Hello"; str = str + " World"; System.out.println("str=" + str);

    結果:

    str=Hello World

    解析:

    實際上,原來String的內容是不變的,只是str由原來指向"Hello"的內存地址轉為指向"Hello World"的內存地址而已,也就是說多開辟了一塊內存區域給"Hello World"字符串。

    2) 通過反射是可以修改所謂的“不可變”對象

    // 創建字符串"Hello World", 并賦給引用s String s = "Hello World"; System.out.println("s = " + s); // Hello World // 獲取String類中的value字段 Field valueFieldOfString = String.class.getDeclaredField("value"); // 改變value屬性的訪問權限 valueFieldOfString.setAccessible(true); // 獲取s對象上的value屬性的值 char[] value = (char[]) valueFieldOfString.get(s); // 改變value所引用的數組中的第5個字符 value[5] = '_'; System.out.println("s = " + s); // Hello_World

    結果:

    s = Hello Worlds = Hello_World

    解析:

    用反射可以訪問私有成員, 然后反射出String對象中的value屬性, 進而改變通過獲得的value引用改變數組的結構。但是一般我們不會這么做,這里只是簡單提一下有這個東西。

    什么是反射機制?反射機制的應用場景有哪些?

    反射機制介紹

    JAVA反射機制是在運行狀態中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱為java語言的反射機制。

    靜態編譯和動態編譯

    • 靜態編譯:在編譯時確定類型,綁定對象
    • 動態編譯:運行時確定類型,綁定對象

    反射機制優缺點

    • 優點: 運行期類型的判斷,動態加載類,提高代碼靈活度。
    • 缺點: 性能瓶頸:反射相當于一系列解釋操作,通知 JVM 要做的事情,性能比直接的java代碼要慢很多。

    反射的應用場景

    反射是框架設計的靈魂。

    在我們平時的項目開發過程中,基本上很少會直接使用到反射機制,但這不能說明反射機制沒有用,實際上有很多設計、開發都與反射機制有關,例如模塊化的開發,通過反射去調用對應的字節碼;動態代理設計模式也采用了反射機制,還有我們日常使用的 Spring/Hibernate 等框架也大量使用到了反射機制。

    舉例:①我們在使用JDBC連接數據庫時使用Class.forName()通過反射加載數據庫的驅動程序;②Spring框架也用到很多反射機制,最經典的就是xml的配置模式。Spring 通過 XML 配置模式裝載 Bean 的過程:1) 將程序內所有 XML 或 Properties 配置文件加載入內存中;2)Java類里面解析xml或properties里面的內容,得到對應實體類的字節碼字符串以及相關的屬性信息; 3)使用反射機制,根據這個字符串獲得某個類的Class實例; 4)動態配置實例的屬性

    推薦閱讀:

    • https://segmentfault.com/a/1190000010162647?utm_source=tuicool&utm_medium=referral
    • https://blog.csdn.net/sinat_38259539/article/details/71799078

    什么是JDK?什么是JRE?什么是JVM?三者之間的聯系與區別

    這幾個是Java中很基本很基本的東西,但是我相信一定還有很多人搞不清楚!為什么呢?因為我們大多數時候在使用現成的編譯工具以及環境的時候,并沒有去考慮這些東西。

    JDK: 顧名思義它是給開發者提供的開發工具箱,是給程序開發者用的。它除了包括完整的JRE(Java Runtime Environment),Java運行環境,還包含了其他供開發者使用的工具包。

    JRE: 普通用戶而只需要安裝JRE(Java Runtime Environment)來運行Java程序。而程序開發者必須安裝JDK來編譯、調試程序。

    JVM: 當我們運行一個程序時,JVM負責將字節碼轉換為特定機器代碼,JVM提供了內存管理/垃圾回收和安全機制等。這種獨立于硬件和操作系統,正是java程序可以一次編寫多處執行的原因。

    區別與聯系:

  • JDK用于開發,JRE用于運行java程序 ;
  • JDK和JRE中都包含JVM ;
  • JVM是java編程語言的核心并且具有平臺獨立性。
  • 什么是字節碼?采用字節碼的最大好處是什么?

    先看下java中的編譯器和解釋器:

    Java中引入了虛擬機的概念,即在機器和編譯程序之間加入了一層抽象的虛擬的機器。這臺虛擬的機器在任何平臺上都提供給編譯程序一個的共同的接口。編譯程序只需要面向虛擬機,生成虛擬機能夠理解的代碼,然后由解釋器來將虛擬機代碼轉換為特定系統的機器碼執行。在Java中,這種供虛擬機理解的代碼叫做字節碼(即擴展名為.class的文件),它不面向任何特定的處理器,只面向虛擬機。每一種平臺的解釋器是不同的,但是實現的虛擬機是相同的。Java源程序經過編譯器編譯后變成字節碼,字節碼由虛擬機解釋執行,虛擬機將每一條要執行的字節碼送給解釋器,解釋器將其翻譯成特定機器上的機器碼,然后在特定的機器上運行。這也就是解釋了Java的編譯與解釋并存的特點。

    Java源代碼---->編譯器---->jvm可執行的Java字節碼(即虛擬指令)---->jvm---->jvm中解釋器----->機器可執行的二進制機器碼---->程序運行。

    采用字節碼的好處:

    Java語言通過字節碼的方式,在一定程度上解決了傳統解釋型語言執行效率低的問題,同時又保留了解釋型語言可移植的特點。所以Java程序運行時比較高效,而且,由于字節碼并不專對一種特定的機器,因此,Java程序無須重新編譯便可在多種不同的計算機上運行。

    Java和C++的區別

    我知道很多人沒學過C++,但是面試官就是沒事喜歡拿咱們Java和C++比呀!沒辦法!!!就算沒學過C++,也要記下來!

    • 都是面向對象的語言,都支持封裝、繼承和多態
    • Java不提供指針來直接訪問內存,程序內存更加安全
    • Java的類是單繼承的,C++支持多重繼承;雖然Java的類不可以多繼承,但是接口可以多繼承。
    • Java有自動內存管理機制,不需要程序員手動釋放無用內存

    接口和抽象類的區別是什么?

  • 接口的方法默認是public,所有方法在接口中不能有實現,抽象類可以有非抽象的方法
  • 接口中的實例變量默認是final類型的,而抽象類中則不一定
  • 一個類可以實現多個接口,但最多只能實現一個抽象類
  • 一個類實現接口的話要實現接口的所有方法,而抽象類不一定
  • 接口不能用new實例化,但可以聲明,但是必須引用一個實現該接口的對象 從設計層面來說,抽象是對類的抽象,是一種模板設計,接口是行為的抽象,是一種行為的規范。
  • 注意:Java8 后接口可以有默認實現( default )。

    成員變量與局部變量的區別有那些?

  • 從語法形式上,看成員變量是屬于類的,而局部變量是在方法中定義的變量或是方法的參數;成員變量可以被public,private,static等修飾符所修飾,而局部變量不能被訪問控制修飾符及static所修飾;但是,成員變量和局部變量都能被final所修飾;
  • 從變量在內存中的存儲方式來看,成員變量是對象的一部分,而對象存在于堆內存,局部變量存在于棧內存
  • 從變量在內存中的生存時間上看,成員變量是對象的一部分,它隨著對象的創建而存在,而局部變量隨著方法的調用而自動消失。
  • 成員變量如果沒有被賦初值,則會自動以類型的默認值而賦值(一種情況例外被final修飾但沒有被static修飾的成員變量必須顯示地賦值);而局部變量則不會自動賦值。
  • 重載和重寫的區別

    重載: 發生在同一個類中,方法名必須相同,參數類型不同、個數不同、順序不同,方法返回值和訪問修飾符可以不同,發生在編譯時。

    重寫: 發生在父子類中,方法名、參數列表必須相同,返回值范圍小于等于父類,拋出的異常范圍小于等于父類,訪問修飾符范圍大于等于父類;如果父類方法訪問修飾符為private則子類就不能重寫該方法。

    字符型常量和字符串常量的區別

    1) 形式上:字符常量是單引號引起的一個字符字符串常量是雙引號引起的若干個字符2) 含義上:字符常量相當于一個整形值(ASCII值),可以參加表達式運算字符串常量代表一個地址值(該字符串在內存中存放位置)3) 占內存大小字符常量只占一個字節字符串常量占若干個字節(至少一個字符結束標志)

    QQ討論群組:984370849 706564342 歡迎加入討論

    想要深入學習的同學們可以加入QQ群討論,有全套資源分享,經驗探討,沒錯,我們等著你,分享互相的故事!

    總結

    以上是生活随笔為你收集整理的string转为char数组_StringBuilder的区别是什么?String是不可变?一点课堂(多岸学院)...的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。