摘要:與都繼承自類(lèi),在中也是使用字符數(shù)組保存字符串,,這兩種對(duì)象都是可變的。采用字節(jié)碼的好處語(yǔ)言通過(guò)字節(jié)碼的方式,在一定程度上解決了傳統(tǒng)解釋型語(yǔ)言執(zhí)行效率低的問(wèn)題,同時(shí)又保留了解釋型語(yǔ)言可移植的特點(diǎn)。
String和StringBuffer、StringBuilder的區(qū)別是什么?String為什么是不可變的? String和StringBuffer、StringBuilder的區(qū)別
可變性
String類(lèi)中使用字符數(shù)組:private final char value[]保存字符串,所以String對(duì)象是不可變的。StringBuilder與StringBuffer都繼承自AbstractStringBuilder類(lèi),在AbstractStringBuilder中也是使用字符數(shù)組保存字符串,char[]value,這兩種對(duì)象都是可變的。
線程安全性
String中的對(duì)象是不可變的,也就可以理解為常量,線程安全。AbstractStringBuilder是StringBuilder與StringBuffer的公共父類(lèi),定義了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。StringBuffer對(duì)方法加了同步鎖或者對(duì)調(diào)用的方法加了同步鎖,所以是線程安全的。StringBuilder并沒(méi)有對(duì)方法進(jìn)行加同步鎖,所以是非線程安全的。
性能
每次對(duì)String 類(lèi)型進(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é):
如果要操作少量的數(shù)據(jù)用 = String
單線程操作字符串緩沖區(qū) 下操作大量數(shù)據(jù) = StringBuilder
多線程操作字符串緩沖區(qū) 下操作大量數(shù)據(jù) = StringBuffer
String為什么是不可變的嗎?簡(jiǎn)單來(lái)說(shuō)就是String類(lèi)利用了final修飾的char類(lèi)型數(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類(lèi)中的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 World s = 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è)類(lèi),都能夠知道這個(gè)類(lèi)的所有屬性和方法;對(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í)確定類(lèi)型,綁定對(duì)象
動(dòng)態(tài)編譯:運(yùn)行時(shí)確定類(lèi)型,綁定對(duì)象
反射機(jī)制優(yōu)缺點(diǎn)優(yōu)點(diǎn): 運(yùn)行期類(lèi)型的判斷,動(dòng)態(tài)加載類(lè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類(lèi)里面解析xml或properties里面的內(nèi)容,得到對(duì)應(yīng)實(shí)體類(lèi)的字節(jié)碼字符串以及相關(guān)的屬性信息; 3)使用反射機(jī)制,根據(jù)這個(gè)字符串獲得某個(gè)類(lèi)的Class實(shí)例; 4)動(dòng)態(tài)配置實(shí)例的屬性
推薦閱讀:
Reflection:Java反射機(jī)制的應(yīng)用場(chǎng)景
Java基礎(chǔ)之—反射(非常重要)
什么是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程序可以一次編寫(xiě)多處執(zhí)行的原因。
區(qū)別與聯(lián)系:
JDK用于開(kāi)發(fā),JRE用于運(yùn)行java程序 ;
JDK和JRE中都包含JVM ;
JVM是java編程語(yǔ)言的核心并且具有平臺(tái)獨(dú)立性。
什么是字節(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é)碼并不專(zhuān)對(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的類(lèi)是單繼承的,C++支持多重繼承;雖然Java的類(lèi)不可以多繼承,但是接口可以多繼承。
Java有自動(dòng)內(nèi)存管理機(jī)制,不需要程序員手動(dòng)釋放無(wú)用內(nèi)存
接口和抽象類(lèi)的區(qū)別是什么?接口的方法默認(rèn)是public,所有方法在接口中不能有實(shí)現(xiàn),抽象類(lèi)可以有非抽象的方法
接口中的實(shí)例變量默認(rèn)是final類(lèi)型的,而抽象類(lèi)中則不一定
一個(gè)類(lèi)可以實(shí)現(xiàn)多個(gè)接口,但最多只能實(shí)現(xiàn)一個(gè)抽象類(lèi)
一個(gè)類(lèi)實(shí)現(xiàn)接口的話要實(shí)現(xiàn)接口的所有方法,而抽象類(lèi)不一定
接口不能用new實(shí)例化,但可以聲明,但是必須引用一個(gè)實(shí)現(xiàn)該接口的對(duì)象 從設(shè)計(jì)層面來(lái)說(shuō),抽象是對(duì)類(lèi)的抽象,是一種模板設(shè)計(jì),接口是行為的抽象,是一種行為的規(guī)范。
成員變量與局部變量的區(qū)別有那些?從語(yǔ)法形式上,看成員變量是屬于類(lèi)的,而局部變量是在方法中定義的變量或是方法的參數(shù);成員變量可以被public,private,static等修飾符所修飾,而局部變量不能被訪問(wèn)控制修飾符及static所修飾;但是,成員變量和局部變量都能被final所修飾;
從變量在內(nèi)存中的存儲(chǔ)方式來(lái)看,成員變量是對(duì)象的一部分,而對(duì)象存在于堆內(nèi)存,局部變量存在于棧內(nèi)存
從變量在內(nèi)存中的生存時(shí)間上看,成員變量是對(duì)象的一部分,它隨著對(duì)象的創(chuàng)建而存在,而局部變量隨著方法的調(diào)用而自動(dòng)消失。
成員變量如果沒(méi)有被賦初值,則會(huì)自動(dòng)以類(lèi)型的默認(rèn)值而賦值(一種情況例外被final修飾但沒(méi)有被static修飾的成員變量必須顯示地賦值);而局部變量則不會(huì)自動(dòng)賦值。
重載和重寫(xiě)的區(qū)別重載: 發(fā)生在同一個(gè)類(lèi)中,方法名必須相同,參數(shù)類(lèi)型不同、個(gè)數(shù)不同、順序不同,方法返回值和訪問(wèn)修飾符可以不同,發(fā)生在編譯時(shí)。
重寫(xiě): 發(fā)生在父子類(lèi)中,方法名、參數(shù)列表必須相同,返回值范圍小于等于父類(lèi),拋出的異常范圍小于等于父類(lèi),訪問(wèn)修飾符范圍大于等于父類(lèi);如果父類(lèi)方法訪問(wèn)修飾符為private則子類(lèi)就不能重寫(xiě)該方法。
字符型常量和字符串常量的區(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)志)
精選互聯(lián)網(wǎng)架構(gòu)師視頻、十多套精選實(shí)戰(zhàn)項(xiàng)目視頻、黑馬內(nèi)部視頻、極客學(xué)院+北風(fēng)網(wǎng)+黑馬大數(shù)據(jù)工程師視頻、5套精選Java面試指南視頻等等。
關(guān)注微信公眾號(hào)“Java面試通關(guān)手冊(cè)”回復(fù)關(guān)鍵字“1"即可免費(fèi)領(lǐng)?。?/strong>
開(kāi)源文檔推薦Java-Guide: Java面試通關(guān)手冊(cè)(Java學(xué)習(xí)指南)Java Interview Customs Manual (Java Study Guide)。star:1.9k。
Github地址:https://github.com/Snailclimb/Java-Guide
文檔定位:一個(gè)專(zhuān)門(mén)為Java后端工程師準(zhǔn)備的開(kāi)源文檔,相信不論你是Java新手還是已經(jīng)成為一名Java工程師都能從這份文檔中收獲到一些東西。
參考:
https://segmentfault.com/a/11...
https://blog.csdn.net/sinat_3...
你若盛開(kāi),清風(fēng)自來(lái)。 歡迎關(guān)注我的微信公眾號(hào):“Java面試通關(guān)手冊(cè)”,一個(gè)有溫度的微信公眾號(hào)。公眾號(hào)有大量資料,回復(fù)關(guān)鍵字“1”你可能看到想要的東西哦!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/76724.html
摘要:地址面試必備最最最常見(jiàn)的面試題總結(jié)第一周一中的值傳遞和引用傳遞非常重要首先要明確的是對(duì)象傳遞數(shù)組類(lèi)接口是引用傳遞,原始類(lèi)型數(shù)據(jù)整型浮點(diǎn)型字符型布爾型傳遞是值傳遞。這個(gè)哈希碼的作用是確定該對(duì)象在哈希表中的索引位置。 showImg(https://segmentfault.com/img/remote/1460000015923339?w=922&h=519); 這里會(huì)分享一些出現(xiàn)頻率極...
摘要:順便一說(shuō),這首歌的原唱是秋田,中島當(dāng)年嗓子壞了,才有這歌。中文是直接翻譯來(lái)的,作曲是秋田。一部電影春夏秋冬又一春春夏秋冬又一春是由金基德執(zhí)導(dǎo),金英民吳英秀金基德主演的一部韓國(guó)電影。年月日于韓國(guó)上映。 原鏈接: http://bluezhan.me/weekly/#/9-2 1、web前端 Angular vs. React vs. Vue: A 2017 comparison 9 S...
摘要:順便一說(shuō),這首歌的原唱是秋田,中島當(dāng)年嗓子壞了,才有這歌。中文是直接翻譯來(lái)的,作曲是秋田。一部電影春夏秋冬又一春春夏秋冬又一春是由金基德執(zhí)導(dǎo),金英民吳英秀金基德主演的一部韓國(guó)電影。年月日于韓國(guó)上映。 原鏈接: http://bluezhan.me/weekly/#/9-2 1、web前端 Angular vs. React vs. Vue: A 2017 comparison 9 S...
閱讀 2300·2023-04-26 00:23
閱讀 1003·2021-09-08 09:45
閱讀 2544·2019-08-28 18:20
閱讀 2686·2019-08-26 13:51
閱讀 1700·2019-08-26 10:32
閱讀 1493·2019-08-26 10:24
閱讀 2122·2019-08-26 10:23
閱讀 2294·2019-08-23 18:10