【蓝桥杯Java_C组·从零开始卷】第一节、环境与变量类型运算符与类型分析
B站高清回放地址:
【https://www.bilibili.com/video/BV1Bm4y1Q7Wt?spm_id_from=333.999.0.0】
目錄
一、Java環(huán)境搭建與使用(Eclipse——1.6JDK)
二、主函數(shù)
三、變量類型
Java中簡(jiǎn)基本數(shù)據(jù)類型的轉(zhuǎn)型:
Java中的高精度數(shù):
四、運(yùn)算符
一元運(yùn)算符(一元運(yùn)算符有1個(gè)操作數(shù))
輸出【false】?
二元運(yùn)算符(二元運(yùn)算符有2個(gè)操作數(shù))
三元運(yùn)算符(三元運(yùn)算符有3個(gè)操作數(shù))
五、類型分析(堆棧)
1. 棧(stack)與堆(heap)都是Java用來(lái)在Ram(隨機(jī)存取存儲(chǔ)器)中存放數(shù)據(jù)的地方。
2. 棧的優(yōu)勢(shì)是,存取速度比堆要快,僅次于直接位于CPU中的寄存器。
3. Java中的數(shù)據(jù)類型有兩種。
4.String是一個(gè)特殊的包裝類數(shù)據(jù)。
5. 關(guān)于String str = "abc"的內(nèi)部工作。
6. 數(shù)據(jù)類型包裝類的值不可修改。
7. 結(jié)論與建議:
一、Java環(huán)境搭建與使用(Eclipse——1.6JDK)
下載地址【https://download.csdn.net/download/feng8403000/69430455】·免費(fèi)
?解壓即可用,非常方便。
二、主函數(shù)
基礎(chǔ)結(jié)構(gòu)
package Action;//包名public class test {//類名public static void main(String[] args) {//主函數(shù)//花括號(hào){}內(nèi)是作用域}}三、變量類型
??int:int為整數(shù)類型,存儲(chǔ)的時(shí)候,用4個(gè)字節(jié)存儲(chǔ),范圍為-2,147,483,648到2,147,483,647,在變量初始化的時(shí)候,int類型的默認(rèn)值為0。
??short:short也屬于整數(shù)類型,在存儲(chǔ)的時(shí)候,用2個(gè)字節(jié)存儲(chǔ),范圍為-32,768到32,767,在變量初始化的時(shí)候,short類型的默認(rèn)值為0,一般情況下,因?yàn)镴ava本身轉(zhuǎn)型的原因,可以直接寫(xiě)為0。
??long:long也屬于整數(shù)類型,在存儲(chǔ)的時(shí)候,用8個(gè)字節(jié)存儲(chǔ),范圍為-9,223,372,036,854,775,808到9,223,372,036,?854,775,807,在變量初始化的時(shí)候,long類型的默認(rèn)值為0L或0l,也可直接寫(xiě)為0。
??byte:byte同樣屬于整數(shù)類型,在存儲(chǔ)的時(shí)候,用1個(gè)字節(jié)來(lái)存儲(chǔ),范圍為-128到127,在變量初始化的時(shí)候,byte類型的默認(rèn)值也為0。
??float:float屬于實(shí)數(shù)類型,在存儲(chǔ)的時(shí)候,用4個(gè)字節(jié)來(lái)存儲(chǔ),范圍為32位IEEEE?754單精度范圍,在變量初始化的時(shí)候,float的默認(rèn)值為0.0f或0.0F,在初始化的時(shí)候可以寫(xiě)0.0。
??double:double同樣屬于實(shí)數(shù)類型,在存儲(chǔ)的時(shí)候,用8個(gè)字節(jié)來(lái)存儲(chǔ),范圍為64位IEEE?754雙精度范圍,在變量初始化的時(shí)候,double的默認(rèn)值為0.0。
??char:char屬于字符類型,在存儲(chǔ)的時(shí)候用2個(gè)字節(jié)來(lái)存儲(chǔ),因?yàn)镴ava本身的字符集不是用ASCII碼來(lái)進(jìn)行存儲(chǔ),是使用的16位Unicode字符集,它的字符范圍即是Unicode的字符范圍,在變量初始化的時(shí)候,char類型的默認(rèn)值為'u0000'。
??boolean:boolean屬于布爾類型,在存儲(chǔ)的時(shí)候不使用字節(jié),僅僅使用1位來(lái)存儲(chǔ),范圍僅僅為0和1,其字面量為true和false,而boolean變量在初始化的時(shí)候變量的默認(rèn)值為false。
通過(guò)包裝類獲取其最大值與最小值:
System.out.println(Byte.MAX_VALUE); System.out.println(Byte.MIN_VALUE); System.out.println(Short.MAX_VALUE); System.out.println(Short.MIN_VALUE); System.out.println(Integer.MAX_VALUE); System.out.println(Integer.MIN_VALUE); System.out.println(Long.MAX_VALUE); System.out.println(Long.MIN_VALUE);浮點(diǎn)數(shù)屬于科學(xué)計(jì)數(shù)法顯示。?
?String:
字符串類,顧名思義,就是操作字符串的類。可以用來(lái)存儲(chǔ)字符串。
???3)相關(guān)介紹:
??在Java基本類型在使用字面量賦值的時(shí)候,有幾個(gè)簡(jiǎn)單的特性如下:
? 【1】當(dāng)整數(shù)類型的數(shù)據(jù)使用字面量賦值的時(shí)候,默認(rèn)值為int類型,就是直接使用0或者其他數(shù)字的時(shí)候,值的類型為int類型,所以當(dāng)使用long?a?=?0這種賦值方式的時(shí)候,JVM內(nèi)部存在數(shù)據(jù)轉(zhuǎn)換。
??【2】當(dāng)實(shí)數(shù)類型的數(shù)據(jù)使用字面量賦值的時(shí)候,默認(rèn)值為double類型,就是當(dāng)字面兩出現(xiàn)的時(shí)候,JVM會(huì)使用double類型的數(shù)據(jù)類型。???(*:以上兩點(diǎn)在轉(zhuǎn)型中進(jìn)行詳細(xì)說(shuō)明。)
??【3】從JDK?5.0開(kāi)始,Java里面出現(xiàn)了自動(dòng)拆箱解箱的操作,基于這點(diǎn)需要做一定的說(shuō)明:
??對(duì)應(yīng)原始的數(shù)據(jù)類型,每種數(shù)據(jù)類型都存在一個(gè)復(fù)雜類型的封裝類,分別為Boolean、Short、Float、Double、Byte、Int、Long、Character,這些類型都是內(nèi)置的封裝類,這些封裝類(Wrapper)提供了很直觀的方法,針對(duì)封裝類需要說(shuō)明的是,每種封裝類都有一個(gè)xxxValue()的方法,通過(guò)這種方法可以把它引用的對(duì)象里面的值轉(zhuǎn)化成為原始變量的值,不僅僅如此,每個(gè)封裝類都還存在一個(gè)valueOf(String)的方法直接把字符串對(duì)象轉(zhuǎn)換為相應(yīng)的簡(jiǎn)單類型。???在JDK?5.0之前,沒(méi)有存在自動(dòng)拆解箱的操作,即Auto?Box操作,所以在這之前是不能使用以下方式的賦值代碼的:
Integer?a?=?0;?//這種賦值方式不能夠在JDK?1.4以及以下的JDK編譯器中通過(guò)
但是JDK?5.0出現(xiàn)了自動(dòng)拆解箱的操作,所以在JDK?5.0以上的編譯器中,以上的代碼是可以通過(guò)的,關(guān)于自動(dòng)拆箱解箱我會(huì)另外用一篇1.4到5.0的升級(jí)加以詳細(xì)說(shuō)明。
Java中簡(jiǎn)基本數(shù)據(jù)類型的轉(zhuǎn)型:
? Java中的簡(jiǎn)單數(shù)據(jù)類型的轉(zhuǎn)換分為兩種:自動(dòng)轉(zhuǎn)換和強(qiáng)制轉(zhuǎn)換?
??1)自動(dòng)轉(zhuǎn)換:
??當(dāng)一個(gè)較“小”的數(shù)據(jù)和較“大”的數(shù)據(jù)一起運(yùn)算的時(shí)候,系統(tǒng)將自動(dòng)將較“小”的數(shù)據(jù)轉(zhuǎn)換為較“大”的數(shù)據(jù),再進(jìn)行運(yùn)算。
??在方法調(diào)用過(guò)程,如果實(shí)際參數(shù)較“小”,而函數(shù)的形參比較“大”的時(shí)候,除非有匹配的方法,否則會(huì)直接使用較“大”的形參函數(shù)進(jìn)行調(diào)用。
???2)強(qiáng)制轉(zhuǎn)換:
??將“大”數(shù)據(jù)轉(zhuǎn)換為“小”數(shù)據(jù)時(shí),可以使用強(qiáng)制類型轉(zhuǎn)換,在強(qiáng)制類型轉(zhuǎn)換的時(shí)候必須使用下邊這種語(yǔ)句:?int?a?=?(int)3.14;
??只是在上邊這種類型轉(zhuǎn)換的時(shí)候,有可能會(huì)出現(xiàn)精度損失。???關(guān)于類型的自動(dòng)提升,遵循下邊的規(guī)則:???所有的byte、short、char類型的值將提升為int類型;???如果有一個(gè)操作數(shù)是long類型,計(jì)算結(jié)果是long類型;???如果有一個(gè)操作數(shù)是float類型,計(jì)算結(jié)果是float類型;
如果有一個(gè)操作數(shù)是double類型,計(jì)算結(jié)果是double類型;
??自動(dòng)類型轉(zhuǎn)換圖如下:
??byte->short(char)->int->long->float->double???如果是強(qiáng)制轉(zhuǎn)換的時(shí)候,就將上邊的圖反過(guò)來(lái)??
? 3)轉(zhuǎn)換附加:
??當(dāng)兩個(gè)類型進(jìn)行自動(dòng)轉(zhuǎn)換的時(shí)候,需要滿足條件:
【1】這兩種類型是兼容的,
【2】目的類型的數(shù)值范圍應(yīng)該比源轉(zhuǎn)換值的范圍要大。而拓展范圍就遵循上邊的自動(dòng)類型轉(zhuǎn)換樹(shù),當(dāng)這兩個(gè)條件都滿足的時(shí)候,拓展轉(zhuǎn)換才會(huì)發(fā)生,而對(duì)于幾個(gè)原始類型轉(zhuǎn)換過(guò)程,根據(jù)兼容性boolean和char應(yīng)該是獨(dú)立的,而其他六種類型是可以兼容的,在強(qiáng)制轉(zhuǎn)換過(guò)程,唯獨(dú)可能特殊的是char和int是可以轉(zhuǎn)換的,不過(guò)會(huì)使用char的ASCII碼值比如:?int?a?=?(int)'a';
??a的值在轉(zhuǎn)換過(guò)后輸出的話,值為97;也可以通過(guò)中文的char進(jìn)行轉(zhuǎn)換int類型。
Java中的高精度數(shù):
? Java提供了兩個(gè)專門(mén)的類進(jìn)行高精度運(yùn)算:BigInteger與BigDecimal,雖然Java原始變量都具有對(duì)應(yīng)的封裝類型,但是這兩個(gè)變量沒(méi)有對(duì)應(yīng)的原始類型,而是通過(guò)方法來(lái)提供這兩種類型的一些運(yùn)算,其含義為普通類型能夠做的操作,這兩個(gè)類型對(duì)應(yīng)都有,只是因?yàn)榫冗^(guò)大可能效率不夠高。至于這兩個(gè)類的具體操作可以參考JDK的相關(guān)API文檔。
關(guān)于數(shù)據(jù)類型的一些技巧:若要求精度的結(jié)果,盡量避免使用float和double:
??float和double類型本身是為了做科學(xué)運(yùn)算,即執(zhí)行二進(jìn)制浮點(diǎn)運(yùn)算而設(shè)計(jì),但是卻不能提供完全精確的結(jié)果,所以在要求精度的數(shù)值中,避免使用float和double,float和double在貨幣運(yùn)算中尤其不合適,要讓float和double精確表達(dá)0.1也是不可能的事。測(cè)試一下下邊這段代碼就明白了:
???System.out.println(3.02-0.01);
? 結(jié)果是不是出乎意料,這個(gè)結(jié)果并不是偶然,而是JVM本身設(shè)計(jì)的目的決定的。而要解決這個(gè)問(wèn)題,最好的辦法是使用BigDecimal、int或者long進(jìn)行相關(guān)運(yùn)算,特別是貨幣運(yùn)算,使用BigDecimal代替double是一個(gè)很好的辦法。???BigDecimal唯一的缺點(diǎn)在于:BigDecimal沒(méi)有相對(duì)應(yīng)的原始類型,所以在進(jìn)行基本數(shù)值運(yùn)算的時(shí)候,需要進(jìn)行方法調(diào)用才能操作,這樣會(huì)使得和我們的編程習(xí)慣不相符合,若使用int和long,就需要進(jìn)行簡(jiǎn)單的封裝運(yùn)算。
??所以在要求精度答案的計(jì)算任務(wù)里面,一般慎用float和double,如果在進(jìn)行商務(wù)運(yùn)算,并且要求四舍五入或者簡(jiǎn)單的舍入行為,使用BigDecimal可能更加方便。所以盡量避免在精度運(yùn)算中使用float和double,特別是我們常用的貨幣運(yùn)算。
四、運(yùn)算符
一元運(yùn)算符(一元運(yùn)算符有1個(gè)操作數(shù))
- ++,- -都是運(yùn)算符
- ++,- -可分為前+,后+和前-,后減
- 如果++在后面,如:num++ +10;先參與運(yùn)算,然后自身結(jié)果再加一
- 如果++在前面,如:++num +10;先自身加一,然后再參與運(yùn)算
- ?!非,對(duì)表達(dá)式取反
- !true=false
輸出【false】
二元運(yùn)算符(二元運(yùn)算符有2個(gè)操作數(shù))
【+-*/】四則運(yùn)算·簡(jiǎn)單計(jì)算器
【%】取模運(yùn)算·對(duì)12345,做各位上的數(shù)組做累加運(yùn)算。
【&、|、&&、||、^】邏輯運(yùn)算符·值交換·通過(guò)【&和|】判斷一百分制成績(jī)。
int a=5;//101 int b=7;//111 a=a^b;//兩者不同量:010=2 System.out.println(a); b=a^b;//兩者不同:101 System.out.println(b); a=a^b;//再進(jìn)行兩者不同取值:111 System.out.println(a);//二進(jìn)制111 System.out.println(b);//二進(jìn)制101三元運(yùn)算符(三元運(yùn)算符有3個(gè)操作數(shù))
三元運(yùn)算符是軟件編程中的一個(gè)固定格式,語(yǔ)法是“條件表達(dá)式?表達(dá)式1:表達(dá)式2”。使用這個(gè)算法可以使調(diào)用數(shù)據(jù)時(shí)逐級(jí)篩選。
表達(dá)式:“()? :”。
()中進(jìn)行二元運(yùn)算
?再運(yùn)算,就形成三元運(yùn)算符
int x = 10; int y = 5; int z; //如果x大于y 則是true,將x賦值給z; //如果x不大于y 則是false,將y賦值給z; z = (x > y) ? x : y; System.out.println("x = " + x); System.out.println("y = " + y); System.out.println("z = " + z);?
五、類型分析(堆棧)
stack和haep都是內(nèi)存的一部分
stack空間小,速度比較快, 用來(lái)放對(duì)象的引用
heap大,一般所有創(chuàng)建的對(duì)象都放在這里。
棧(stack):是一個(gè)先進(jìn)后出的數(shù)據(jù)結(jié)構(gòu),通常用于保存方法(函數(shù))中的參數(shù),局部變量.
在java中,所有基本類型和引用類型都在棧中存儲(chǔ).棧中數(shù)據(jù)的生存空間一般在當(dāng)前scopes內(nèi)(就是由{...}括起來(lái)的區(qū)域).
堆(heap):是一個(gè)可動(dòng)態(tài)申請(qǐng)的內(nèi)存空間(其記錄空閑內(nèi)存空間的鏈表由操作系統(tǒng)維護(hù)),C中的malloc語(yǔ)句所產(chǎn)生的內(nèi)存空間就在堆中.
在java中,所有使用new xxx()構(gòu)造出來(lái)的對(duì)象都在堆中存儲(chǔ),當(dāng)垃圾回收器檢測(cè)到某對(duì)象未被引用,則自動(dòng)銷毀該對(duì)象.所以,理論上說(shuō)java中對(duì)象的生存空間是沒(méi)有限制的,只要有引用類型指向它,則它就可以在任意地方被使用.
1. 棧(stack)與堆(heap)都是Java用來(lái)在Ram(隨機(jī)存取存儲(chǔ)器)中存放數(shù)據(jù)的地方。
與C++不同,Java自動(dòng)管理?xiàng):投?#xff0c;程序員不能直接地設(shè)置棧或堆。
2. 棧的優(yōu)勢(shì)是,存取速度比堆要快,僅次于直接位于CPU中的寄存器。
但缺點(diǎn)是,存在棧中的數(shù)據(jù)大小與生存期必須是確定的,缺乏靈活性。另外,棧數(shù)據(jù)可以共享,詳見(jiàn)第3點(diǎn)。堆的優(yōu)勢(shì)是可以動(dòng)態(tài)地分配內(nèi)存大小,生存期也不必事先告訴編譯器,Java的垃圾收集器會(huì)自動(dòng)收走這些不再使用的數(shù)據(jù)。但缺點(diǎn)是,由于要在運(yùn)行時(shí)動(dòng)態(tài)分配內(nèi)存,存取速度較慢。
3. Java中的數(shù)據(jù)類型有兩種。
? ? ? ? 一種是基本類型(primitive types), 共有8種,即int, short, long, byte, float, double, boolean, char(注意,并沒(méi)有string的基本類型)。這種類型的定義是通過(guò)諸如int a = 3; long b = 255L;的形式來(lái)定義的,稱為自動(dòng)變量。值得注意的是,自動(dòng)變量存的是字面值,不是類的實(shí)例,即不是類的引用,這里并沒(méi)有類的存在。如int a = 3; 這里的a是一個(gè)指向int類型的引用,指向3這個(gè)字面值。這些字面值的數(shù)據(jù),由于大小可知,生存期可知(這些字面值固定定義在某個(gè)程序塊里面,程序塊退出后,字段值就消失了),出于追求速度的原因,就存在于棧中。
另外,棧有一個(gè)很重要的特殊性,就是存在棧中的數(shù)據(jù)可以共享。假設(shè)我們同時(shí)定義:
編譯器先處理int a = 3;首先它會(huì)在棧中創(chuàng)建一個(gè)變量為a的引用,然后查找有沒(méi)有字面值為3的地址,沒(méi)找到,就開(kāi)辟一個(gè)存放3這個(gè)字面值的地址,然后將a指向3的地址。接著處理int b = 3;在創(chuàng)建完b的引用變量后,由于在棧中已經(jīng)有3這個(gè)字面值,便將b直接指向3的地址。
這樣,就出現(xiàn)了a與b同時(shí)均指向3的情況。特別注意的是,這種字面值的引用與類對(duì)象的引用不同。
假定兩個(gè)類對(duì)象的引用同時(shí)指向一個(gè)對(duì)象,如果一個(gè)對(duì)象引用變量修改了這個(gè)對(duì)象的內(nèi)部狀態(tài),那么另一個(gè)對(duì)象引用變量也即刻反映出這個(gè)變化。
相反,通過(guò)字面值的引用來(lái)修改其值,不會(huì)導(dǎo)致另一個(gè)指向此字面值的引用的值也跟著改變的情況。
如上例,我們定義完a與b的值后,再令a=4;那么,b不會(huì)等于4,還是等于3。在編譯器內(nèi)部,遇到a=4;時(shí),它就會(huì)重新搜索棧中是否有4的字面值,如果沒(méi)有,重新開(kāi)辟地址存放4的值;如果已經(jīng)有了,則直接將a指向這個(gè)地址。因此a值的改變不會(huì)影響到b的值。
? ? ? ? 另一種是包裝類數(shù)據(jù),如Integer, String, Double等將相應(yīng)的基本數(shù)據(jù)類型包裝起來(lái)的類。這些類數(shù)據(jù)全部存在于堆中,Java用new()語(yǔ)句來(lái)顯示地告訴編譯器,在運(yùn)行時(shí)才根據(jù)需要?jiǎng)討B(tài)創(chuàng)建,因此比較靈活,但缺點(diǎn)是要占用更多的時(shí)間。
4.String是一個(gè)特殊的包裝類數(shù)據(jù)。
即可以用String str = new String("abc");的形式來(lái)創(chuàng)建,也可以用String str = "abc";的形式來(lái)創(chuàng)建(作為對(duì)比,在JDK 5.0之前,你從未見(jiàn)過(guò)Integer i = 3;的表達(dá)式,因?yàn)轭惻c字面值是不能通用的,除了String。而在JDK 5.0中,這種表達(dá)式是可以的!因?yàn)榫幾g器在后臺(tái)進(jìn)行Integer i = new Integer(3)的轉(zhuǎn)換!)。
前者是規(guī)范的類的創(chuàng)建過(guò)程,即在Java中,一切都是對(duì)象,而對(duì)象是類的實(shí)例,全部通過(guò)new()的形式來(lái)創(chuàng)建。Java中的有些類,如DateFormat類,可以通過(guò)該類的getInstance()方法來(lái)返回一個(gè)新創(chuàng)建的類,似乎違反了此原則。其實(shí)不然。該類運(yùn)用了單例模式來(lái)返回類的實(shí)例,只不過(guò)這個(gè)實(shí)例是在該類內(nèi)部通過(guò)new()來(lái)創(chuàng)建的,而getInstance()向外部隱藏了此細(xì)節(jié)。那為什么在String str = "abc";中,并沒(méi)有通過(guò)new()來(lái)創(chuàng)建實(shí)例,是不是違反了上述原則?其實(shí)沒(méi)有。
5. 關(guān)于String str = "abc"的內(nèi)部工作。
Java內(nèi)部將此語(yǔ)句轉(zhuǎn)化為以下幾個(gè)步驟:
(1)先定義一個(gè)名為str的對(duì)String類的對(duì)象引用變量:String str;
(2)在棧中查找有沒(méi)有存放值為"abc"的地址,如果沒(méi)有,則開(kāi)辟一個(gè)存放字面值為"abc"的地址,接著創(chuàng)建一個(gè)新的String類的對(duì)象o,并將o的字符串值指向這個(gè)地址,而且在棧中這個(gè)地址旁邊記下這個(gè)引用的對(duì)象o。如果已經(jīng)有了值為"abc"的地址,則查找對(duì)象o,并返回o的地址。
(3)將str指向?qū)ο髈的地址。
值得注意的是,一般String類中字符串值都是直接存值的。但像String str = "abc";這種場(chǎng)合下,其字符串值卻是保存了一個(gè)指向存在棧中數(shù)據(jù)的引用!
為了更好地說(shuō)明這個(gè)問(wèn)題,我們可以通過(guò)以下的幾個(gè)代碼進(jìn)行驗(yàn)證。
注意,我們這里并不用str1.equals(str2);的方式,因?yàn)檫@將比較兩個(gè)字符串的值是否相等。==號(hào),根據(jù)JDK的說(shuō)明,只有在兩個(gè)引用都指向了同一個(gè)對(duì)象時(shí)才返回真值。而我們?cè)谶@里要看的是,str1與str2是否都指向了同一個(gè)對(duì)象。
結(jié)果說(shuō)明,JVM創(chuàng)建了兩個(gè)引用str1和str2,但只創(chuàng)建了一個(gè)對(duì)象,而且兩個(gè)引用都指向了這個(gè)對(duì)象。
我們?cè)賮?lái)更進(jìn)一步,將以上代碼改成:
這就是說(shuō),賦值的變化導(dǎo)致了類對(duì)象引用的變化,str1指向了另外一個(gè)新對(duì)象!而str2仍舊指向原來(lái)的對(duì)象。上例中,當(dāng)我們將str1的值改為"bcd"時(shí),JVM發(fā)現(xiàn)在棧中沒(méi)有存放該值的地址,便開(kāi)辟了這個(gè)地址,并創(chuàng)建了一個(gè)新的對(duì)象,其字符串的值指向這個(gè)地址。
事實(shí)上,String類被設(shè)計(jì)成為不可改變(final)的類。如果你要改變其值,可以,但JVM在運(yùn)行時(shí)根據(jù)新值悄悄創(chuàng)建了一個(gè)新對(duì)象,然后將這個(gè)對(duì)象的地址返回給原來(lái)類的引用。這個(gè)創(chuàng)建過(guò)程雖說(shuō)是完全自動(dòng)進(jìn)行的,但它畢竟占用了更多的時(shí)間。在對(duì)時(shí)間要求比較敏感的環(huán)境中,會(huì)帶有一定的不良影響。
再修改原來(lái)代碼:
str3這個(gè)對(duì)象的引用直接指向str1所指向的對(duì)象(注意,str3并沒(méi)有創(chuàng)建新對(duì)象)。當(dāng)str1改完其值后,再創(chuàng)建一個(gè)String的引用str4,并指向因str1修改值而創(chuàng)建的新的對(duì)象。可以發(fā)現(xiàn),這回str4也沒(méi)有創(chuàng)建新的對(duì)象,從而再次實(shí)現(xiàn)棧中數(shù)據(jù)的共享。
我們?cè)俳又匆韵碌拇a。
創(chuàng)建了兩個(gè)引用。創(chuàng)建了兩個(gè)對(duì)象。兩個(gè)引用分別指向不同的兩個(gè)對(duì)象。
創(chuàng)建了兩個(gè)引用。創(chuàng)建了兩個(gè)對(duì)象。兩個(gè)引用分別指向不同的兩個(gè)對(duì)象。
以上兩段代碼說(shuō)明,只要是用new()來(lái)新建對(duì)象的,都會(huì)在堆中創(chuàng)建,而且其字符串是單獨(dú)存值的,即使與棧中的數(shù)據(jù)相同,也不會(huì)與棧中的數(shù)據(jù)共享。
6. 數(shù)據(jù)類型包裝類的值不可修改。
不僅僅是String類的值不可修改,所有的數(shù)據(jù)類型包裝類都不能更改其內(nèi)部的值。
7. 結(jié)論與建議:
(1)我們?cè)谑褂弥T如String str = "abc";的格式定義類時(shí),總是想當(dāng)然地認(rèn)為,我們創(chuàng)建了String類的對(duì)象str。擔(dān)心陷阱!對(duì)象可能并沒(méi)有被創(chuàng)建!唯一可以肯定的是,指向String類的引用被創(chuàng)建了。至于這個(gè)引用到底是否指向了一個(gè)新的對(duì)象,必須根據(jù)上下文來(lái)考慮,除非你通過(guò)new()方法來(lái)顯要地創(chuàng)建一個(gè)新的對(duì)象。因此,更為準(zhǔn)確的說(shuō)法是,我們創(chuàng)建了一個(gè)指向String類的對(duì)象的引用變量str,這個(gè)對(duì)象引用變量指向了某個(gè)值為"abc"的String類。清醒地認(rèn)識(shí)到這一點(diǎn)對(duì)排除程序中難以發(fā)現(xiàn)的bug是很有幫助的。
(2)使用String str = "abc";的方式,可以在一定程度上提高程序的運(yùn)行速度,因?yàn)镴VM會(huì)自動(dòng)根據(jù)棧中數(shù)據(jù)的實(shí)際情況來(lái)決定是否有必要?jiǎng)?chuàng)建新對(duì)象。而對(duì)于String str = new String("abc");的代碼,則一概在堆中創(chuàng)建新對(duì)象,而不管其字符串值是否相等,是否有必要?jiǎng)?chuàng)建新對(duì)象,從而加重了程序的負(fù)擔(dān)。
(3)當(dāng)比較包裝類里面的數(shù)值是否相等時(shí),用equals()方法;當(dāng)測(cè)試兩個(gè)包裝類的引用是否指向同一個(gè)對(duì)象時(shí),用==。
(4)由于String類的final性質(zhì),當(dāng)String變量需要經(jīng)常變換其值時(shí),應(yīng)該考慮使用StringBuffer類,以提高程序效率。
本節(jié)比較細(xì)致,希望能對(duì)大家有一定的幫助,祝大家藍(lán)橋都能拿一個(gè)好成績(jī)。?
總結(jié)
以上是生活随笔為你收集整理的【蓝桥杯Java_C组·从零开始卷】第一节、环境与变量类型运算符与类型分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【实施工程师之家】linux安装tomc
- 下一篇: 密码强度测试工具包【Java】_测试用例