string转为char数组_StringBuilder的区别是什么?String是不可变?一点课堂(多岸学院)...
String和StringBuffer、StringBuilder的區(qū)別
可變性
簡(jiǎn)單的來(lái)說(shuō):String 類中使用 final 關(guān)鍵字字符數(shù)組保存字符串,private final char value[],所以 String 對(duì)象是不可變的。而StringBuilder 與 StringBuffer 都繼承自 AbstractStringBuilder 類,在 AbstractStringBuilder 中也是使用字符數(shù)組保存字符串char[]value 但是沒(méi)有用 final 關(guān)鍵字修飾,所以這兩種對(duì)象都是可變的。
StringBuilder 與 StringBuffer 的構(gòu)造方法都是調(diào)用父類構(gòu)造方法也就是 AbstractStringBuilder 實(shí)現(xiàn)的,大家可以自行查閱源碼。
AbstractStringBuilder.java
abstract class AbstractStringBuilder implements Appendable, CharSequence { char[] value; int count; AbstractStringBuilder() { } AbstractStringBuilder(int capacity) { value = new char[capacity]; }線程安全性
String 中的對(duì)象是不可變的,也就可以理解為常量,線程安全。AbstractStringBuilder 是 StringBuilder 與 StringBuffer 的公共父類,定義了一些字符串的基本操作,如 expandCapacity、append、insert、indexOf 等公共方法。StringBuffer 對(duì)方法加了同步鎖或者對(duì)調(diào)用的方法加了同步鎖,所以是線程安全的。StringBuilder 并沒(méi)有對(duì)方法進(jìn)行加同步鎖,所以是非線程安全的。
性能
每次對(duì) String 類型進(jìn)行改變的時(shí)候,都會(huì)生成一個(gè)新的 String 對(duì)象,然后將指針指向新的 String 對(duì)象。StringBuffer 每次都會(huì)對(duì) StringBuffer 對(duì)象本身進(jìn)行操作,而不是生成新的對(duì)象并改變對(duì)象引用。相同情況下使用 StirngBuilder 相比使用 StringBuffer 僅能獲得 10%~15% 左右的性能提升,但卻要冒多線程不安全的風(fēng)險(xiǎn)。
對(duì)于三者使用的總結(jié):
String為什么是不可變的嗎?
簡(jiǎn)單來(lái)說(shuō)就是String類利用了final修飾的char類型數(shù)組存儲(chǔ)字符,源碼如下圖所以:
/** The value is used for character storage. */ private final char value[];String真的是不可變的嗎?
我覺(jué)得如果別人問(wèn)這個(gè)問(wèn)題的話,回答不可變就可以了。下面只是給大家看兩個(gè)有代表性的例子:
1) String不可變但不代表引用不可以變
String str = "Hello"; str = str + " World"; System.out.println("str=" + str);結(jié)果:
str=Hello World解析:
實(shí)際上,原來(lái)String的內(nèi)容是不變的,只是str由原來(lái)指向"Hello"的內(nèi)存地址轉(zhuǎn)為指向"Hello World"的內(nèi)存地址而已,也就是說(shuō)多開(kāi)辟了一塊內(nèi)存區(qū)域給"Hello World"字符串。
2) 通過(guò)反射是可以修改所謂的“不可變”對(duì)象
// 創(chuàng)建字符串"Hello World", 并賦給引用s String s = "Hello World"; System.out.println("s = " + s); // Hello World // 獲取String類中的value字段 Field valueFieldOfString = String.class.getDeclaredField("value"); // 改變value屬性的訪問(wèn)權(quán)限 valueFieldOfString.setAccessible(true); // 獲取s對(duì)象上的value屬性的值 char[] value = (char[]) valueFieldOfString.get(s); // 改變value所引用的數(shù)組中的第5個(gè)字符 value[5] = '_'; System.out.println("s = " + s); // Hello_World結(jié)果:
s = Hello Worlds = Hello_World解析:
用反射可以訪問(wèn)私有成員, 然后反射出String對(duì)象中的value屬性, 進(jìn)而改變通過(guò)獲得的value引用改變數(shù)組的結(jié)構(gòu)。但是一般我們不會(huì)這么做,這里只是簡(jiǎn)單提一下有這個(gè)東西。
什么是反射機(jī)制?反射機(jī)制的應(yīng)用場(chǎng)景有哪些?
反射機(jī)制介紹
JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱為java語(yǔ)言的反射機(jī)制。
靜態(tài)編譯和動(dòng)態(tài)編譯
- 靜態(tài)編譯:在編譯時(shí)確定類型,綁定對(duì)象
- 動(dòng)態(tài)編譯:運(yùn)行時(shí)確定類型,綁定對(duì)象
反射機(jī)制優(yōu)缺點(diǎn)
- 優(yōu)點(diǎn): 運(yùn)行期類型的判斷,動(dòng)態(tài)加載類,提高代碼靈活度。
- 缺點(diǎn): 性能瓶頸:反射相當(dāng)于一系列解釋操作,通知 JVM 要做的事情,性能比直接的java代碼要慢很多。
反射的應(yīng)用場(chǎng)景
反射是框架設(shè)計(jì)的靈魂。
在我們平時(shí)的項(xiàng)目開(kāi)發(fā)過(guò)程中,基本上很少會(huì)直接使用到反射機(jī)制,但這不能說(shuō)明反射機(jī)制沒(méi)有用,實(shí)際上有很多設(shè)計(jì)、開(kāi)發(fā)都與反射機(jī)制有關(guān),例如模塊化的開(kāi)發(fā),通過(guò)反射去調(diào)用對(duì)應(yīng)的字節(jié)碼;動(dòng)態(tài)代理設(shè)計(jì)模式也采用了反射機(jī)制,還有我們?nèi)粘J褂玫?Spring/Hibernate 等框架也大量使用到了反射機(jī)制。
舉例:①我們?cè)谑褂肑DBC連接數(shù)據(jù)庫(kù)時(shí)使用Class.forName()通過(guò)反射加載數(shù)據(jù)庫(kù)的驅(qū)動(dòng)程序;②Spring框架也用到很多反射機(jī)制,最經(jīng)典的就是xml的配置模式。Spring 通過(guò) XML 配置模式裝載 Bean 的過(guò)程:1) 將程序內(nèi)所有 XML 或 Properties 配置文件加載入內(nèi)存中;2)Java類里面解析xml或properties里面的內(nèi)容,得到對(duì)應(yīng)實(shí)體類的字節(jié)碼字符串以及相關(guān)的屬性信息; 3)使用反射機(jī)制,根據(jù)這個(gè)字符串獲得某個(gè)類的Class實(shí)例; 4)動(dòng)態(tài)配置實(shí)例的屬性
推薦閱讀:
- https://segmentfault.com/a/1190000010162647?utm_source=tuicool&utm_medium=referral
- https://blog.csdn.net/sinat_38259539/article/details/71799078
什么是JDK?什么是JRE?什么是JVM?三者之間的聯(lián)系與區(qū)別
這幾個(gè)是Java中很基本很基本的東西,但是我相信一定還有很多人搞不清楚!為什么呢?因?yàn)槲覀兇蠖鄶?shù)時(shí)候在使用現(xiàn)成的編譯工具以及環(huán)境的時(shí)候,并沒(méi)有去考慮這些東西。
JDK: 顧名思義它是給開(kāi)發(fā)者提供的開(kāi)發(fā)工具箱,是給程序開(kāi)發(fā)者用的。它除了包括完整的JRE(Java Runtime Environment),Java運(yùn)行環(huán)境,還包含了其他供開(kāi)發(fā)者使用的工具包。
JRE: 普通用戶而只需要安裝JRE(Java Runtime Environment)來(lái)運(yùn)行Java程序。而程序開(kāi)發(fā)者必須安裝JDK來(lái)編譯、調(diào)試程序。
JVM: 當(dāng)我們運(yùn)行一個(gè)程序時(shí),JVM負(fù)責(zé)將字節(jié)碼轉(zhuǎn)換為特定機(jī)器代碼,JVM提供了內(nèi)存管理/垃圾回收和安全機(jī)制等。這種獨(dú)立于硬件和操作系統(tǒng),正是java程序可以一次編寫多處執(zhí)行的原因。
區(qū)別與聯(lián)系:
什么是字節(jié)碼?采用字節(jié)碼的最大好處是什么?
先看下java中的編譯器和解釋器:
Java中引入了虛擬機(jī)的概念,即在機(jī)器和編譯程序之間加入了一層抽象的虛擬的機(jī)器。這臺(tái)虛擬的機(jī)器在任何平臺(tái)上都提供給編譯程序一個(gè)的共同的接口。編譯程序只需要面向虛擬機(jī),生成虛擬機(jī)能夠理解的代碼,然后由解釋器來(lái)將虛擬機(jī)代碼轉(zhuǎn)換為特定系統(tǒng)的機(jī)器碼執(zhí)行。在Java中,這種供虛擬機(jī)理解的代碼叫做字節(jié)碼(即擴(kuò)展名為.class的文件),它不面向任何特定的處理器,只面向虛擬機(jī)。每一種平臺(tái)的解釋器是不同的,但是實(shí)現(xiàn)的虛擬機(jī)是相同的。Java源程序經(jīng)過(guò)編譯器編譯后變成字節(jié)碼,字節(jié)碼由虛擬機(jī)解釋執(zhí)行,虛擬機(jī)將每一條要執(zhí)行的字節(jié)碼送給解釋器,解釋器將其翻譯成特定機(jī)器上的機(jī)器碼,然后在特定的機(jī)器上運(yùn)行。這也就是解釋了Java的編譯與解釋并存的特點(diǎn)。
Java源代碼---->編譯器---->jvm可執(zhí)行的Java字節(jié)碼(即虛擬指令)---->jvm---->jvm中解釋器----->機(jī)器可執(zhí)行的二進(jìn)制機(jī)器碼---->程序運(yùn)行。
采用字節(jié)碼的好處:
Java語(yǔ)言通過(guò)字節(jié)碼的方式,在一定程度上解決了傳統(tǒng)解釋型語(yǔ)言執(zhí)行效率低的問(wèn)題,同時(shí)又保留了解釋型語(yǔ)言可移植的特點(diǎn)。所以Java程序運(yùn)行時(shí)比較高效,而且,由于字節(jié)碼并不專對(duì)一種特定的機(jī)器,因此,Java程序無(wú)須重新編譯便可在多種不同的計(jì)算機(jī)上運(yùn)行。
Java和C++的區(qū)別
我知道很多人沒(méi)學(xué)過(guò)C++,但是面試官就是沒(méi)事喜歡拿咱們Java和C++比呀!沒(méi)辦法!!!就算沒(méi)學(xué)過(guò)C++,也要記下來(lái)!
- 都是面向?qū)ο蟮恼Z(yǔ)言,都支持封裝、繼承和多態(tài)
- Java不提供指針來(lái)直接訪問(wèn)內(nèi)存,程序內(nèi)存更加安全
- Java的類是單繼承的,C++支持多重繼承;雖然Java的類不可以多繼承,但是接口可以多繼承。
- Java有自動(dòng)內(nèi)存管理機(jī)制,不需要程序員手動(dòng)釋放無(wú)用內(nèi)存
接口和抽象類的區(qū)別是什么?
注意:Java8 后接口可以有默認(rèn)實(shí)現(xiàn)( default )。
成員變量與局部變量的區(qū)別有那些?
重載和重寫的區(qū)別
重載: 發(fā)生在同一個(gè)類中,方法名必須相同,參數(shù)類型不同、個(gè)數(shù)不同、順序不同,方法返回值和訪問(wèn)修飾符可以不同,發(fā)生在編譯時(shí)。
重寫: 發(fā)生在父子類中,方法名、參數(shù)列表必須相同,返回值范圍小于等于父類,拋出的異常范圍小于等于父類,訪問(wèn)修飾符范圍大于等于父類;如果父類方法訪問(wèn)修飾符為private則子類就不能重寫該方法。
字符型常量和字符串常量的區(qū)別
1) 形式上:字符常量是單引號(hào)引起的一個(gè)字符字符串常量是雙引號(hào)引起的若干個(gè)字符2) 含義上:字符常量相當(dāng)于一個(gè)整形值(ASCII值),可以參加表達(dá)式運(yùn)算字符串常量代表一個(gè)地址值(該字符串在內(nèi)存中存放位置)3) 占內(nèi)存大小字符常量只占一個(gè)字節(jié)字符串常量占若干個(gè)字節(jié)(至少一個(gè)字符結(jié)束標(biāo)志)
QQ討論群組:984370849 706564342 歡迎加入討論
想要深入學(xué)習(xí)的同學(xué)們可以加入QQ群討論,有全套資源分享,經(jīng)驗(yàn)探討,沒(méi)錯(cuò),我們等著你,分享互相的故事!
總結(jié)
以上是生活随笔為你收集整理的string转为char数组_StringBuilder的区别是什么?String是不可变?一点课堂(多岸学院)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 投资金条怎么卖掉
- 下一篇: 申请开通创业板交易,需分三步走