1.構(gòu)造器使用要點(diǎn):
????1.通過(guò)new關(guān)鍵字調(diào)用!!
????2.構(gòu)造器雖然有返回值(返回該類的對(duì)象),但是不能定義返回類型?(返回值的類型肯定是本類),不能在構(gòu)造器里調(diào)用return。
????3.如果我們沒(méi)有定義構(gòu)造器,則系統(tǒng)會(huì)自動(dòng)定義一個(gè)無(wú)參的構(gòu)造函數(shù)。如果已定義則編譯器不會(huì)添加!
????4.構(gòu)造器的方法名必須和類名一致!
1.1.構(gòu)造方法的重載和普通方法一樣:
?
? ? ? 普通方法重載的條件:
? ? ??1.不同的含義:形參類型、形參個(gè)數(shù)、形參順序不同
? ? ? 2.只有返回值不同不構(gòu)成方法的重載
? ? ??如:
????????int?a(String?str){}與?void?a(String?str){}
? ? ??不構(gòu)成方法重載
? ? ??3.只有形參的名稱不同,不構(gòu)成方法的重載
? ? ??如:
????????int?a(String?str){}與int?a(String?s){}
2.垃圾回收機(jī)制:
Java引入了垃圾回收機(jī)制,令C++程序員最頭疼的內(nèi)存管理問(wèn)題迎刃而解。Java程序員可以將更多的精力放到業(yè)務(wù)邏輯上而不是內(nèi)存管理工作上,大大的提高了開(kāi)發(fā)效率。
2.1垃圾回收原理和算法:
·內(nèi)存管理
Java的內(nèi)存管理很大程度指的就是對(duì)象的管理,其中包括對(duì)象空間的分配和釋放。
對(duì)象空間的分配:使用new關(guān)鍵字創(chuàng)建對(duì)象即可
對(duì)象空間的釋放:將對(duì)象賦值null即可。垃圾回收器將負(fù)責(zé)回收所有”不可達(dá)”對(duì)象的內(nèi)存空間。
·垃圾回收過(guò)程(2個(gè)要點(diǎn))
任何一種垃圾回收算法一般要做兩件基本事情:
1. 發(fā)現(xiàn)無(wú)用的對(duì)象
2. 回收無(wú)用對(duì)象占用的內(nèi)存空間。
垃圾回收機(jī)制保證可以將“無(wú)用的對(duì)象”進(jìn)行回收。無(wú)用的對(duì)象指的就是沒(méi)有任何變量引用該對(duì)象。Java的垃圾回收器通過(guò)相關(guān)算法發(fā)現(xiàn)無(wú)用對(duì)象,并進(jìn)行清除和整理。
·垃圾回收相關(guān)算法
1. 引用計(jì)數(shù)法
堆中每個(gè)對(duì)象都有一個(gè)引用計(jì)數(shù)。被引用一次,計(jì)數(shù)加1. 被引用變量值變?yōu)閚ull,則計(jì)數(shù)減1,直到計(jì)數(shù)為0,則表示變成無(wú)用對(duì)象。優(yōu)點(diǎn)是算法簡(jiǎn)單,缺點(diǎn)是“循環(huán)引用的無(wú)用對(duì)象”無(wú)法別識(shí)別。
【示例4-7】循環(huán)引用示例
public?class?Student?{
????String?name;
????Student?friend;//在一個(gè)對(duì)象中又引用了另一個(gè)對(duì)象
????public?static?void?main(String[]?args)?{
????????Student?s1?=?new?Student();
????????Student?s2?=?new?Student();
????????s1.friend?=?s2;
????????s2.friend?=?s1;????????
????????s1?=?null;
????????s2?=?null;
????}
}
s1和s2互相引用對(duì)方,導(dǎo)致他們引用計(jì)數(shù)不為0,但是實(shí)際已經(jīng)無(wú)用,但無(wú)法被識(shí)別。
2. 引用可達(dá)法(根搜索算法)
程序把所有的引用關(guān)系看作一張圖,從一個(gè)節(jié)點(diǎn)GC ROOT開(kāi)始,尋找對(duì)應(yīng)的引用節(jié)點(diǎn),找到這個(gè)節(jié)點(diǎn)以后,繼續(xù)尋找這個(gè)節(jié)點(diǎn)的引用節(jié)點(diǎn),當(dāng)所有的引用節(jié)點(diǎn)尋找完畢之后,剩余的節(jié)點(diǎn)則被認(rèn)為是沒(méi)有被引用到的節(jié)點(diǎn),即無(wú)用的節(jié)點(diǎn)。
2.2通用的分代垃圾回收機(jī)制:
? ??????分代垃圾回收機(jī)制,是基于這樣一個(gè)事實(shí):不同的對(duì)象的生命周期是不一樣的。因此,不同生命周期的對(duì)象可以采取不同的回收算法,以便提高回收效率。我們將對(duì)象分為三種狀態(tài):年輕代、年老代、持久代。JVM將堆內(nèi)存劃分為 Eden、Survivor 和 Tenured/Old 空間。
????(上面的英文翻譯Eden:伊甸園;Survivor :幸存者;Tenured/Old:終身制/ 古老)
1. 年輕代
所有新生成的對(duì)象首先都是放在Eden區(qū)。 年輕代的目標(biāo)就是盡可能快速的收集掉那些生命周期短的對(duì)象,對(duì)應(yīng)的是Minor GC,每次 Minor GC 會(huì)清理年輕代的內(nèi)存,算法采用效率較高的復(fù)制算法,頻繁的操作,但是會(huì)浪費(fèi)內(nèi)存空間。當(dāng)“年輕代”區(qū)域存放滿對(duì)象后,就將對(duì)象存放到年老代區(qū)域。
2. 年老代
在年輕代中經(jīng)歷了N(默認(rèn)15)次垃圾回收后仍然存活的對(duì)象,就會(huì)被放到年老代中。因此,可以認(rèn)為年老代中存放的都是一些生命周期較長(zhǎng)的對(duì)象。年老代對(duì)象越來(lái)越多,我們就需要啟動(dòng)Major GC和Full GC(全量回收),來(lái)一次大掃除,全面清理年輕代區(qū)域和年老代區(qū)域。
3. 持久代(不討論)
用于存放靜態(tài)文件,如Java類、方法等。持久代對(duì)垃圾回收沒(méi)有顯著影響。
.垃圾回收過(guò)程:
1、新創(chuàng)建的對(duì)象,絕大多數(shù)都會(huì)存儲(chǔ)在Eden中,
? ? 2、當(dāng)Eden滿了(達(dá)到一定比例)不能創(chuàng)建新對(duì)象,則觸發(fā)垃圾回收(GC),將無(wú)用對(duì)象清理掉,【觸發(fā)gc就是上一段的一些垃圾回收的算法:引用可達(dá)法、引用可達(dá)法】
???????????然后剩余對(duì)象復(fù)制到某個(gè)Survivor中,如S1,同時(shí)清空Eden區(qū)
? ? 3、當(dāng)Eden區(qū)再次滿了,會(huì)將S1中的不能清空的對(duì)象存到另外一個(gè)Survivor中,如S2,
? ? ? ? ??同時(shí)將Eden區(qū)中的不能清空的對(duì)象,也復(fù)制到S1中,保證Eden和S1,均被清空。
4、重復(fù)多次(默認(rèn)15次)Survivor中沒(méi)有被清理的對(duì)象,則會(huì)復(fù)制到老年代Old(Tenured)區(qū)中,
? ? 5、當(dāng)Old區(qū)滿了,則會(huì)觸發(fā)一個(gè)一次完整地垃圾回收(FullGC),之前新生代的垃圾回收稱為(minorGC)
·Minor GC:
用于清理年輕代區(qū)域。Eden區(qū)滿了就會(huì)觸發(fā)一次Minor GC。清理無(wú)用對(duì)象,將有用對(duì)象復(fù)制到“Survivor1”、“Survivor2”區(qū)中(這兩個(gè)區(qū),大小空間也相同,同一時(shí)刻Survivor1和Survivor2只有一個(gè)在用,一個(gè)為空)
·Major GC:
用于清理老年代區(qū)域。
·Full GC:
用于清理年輕代、年老代區(qū)域。 成本較高,會(huì)對(duì)系統(tǒng)性能產(chǎn)生影響。
2.3 JVM調(diào)優(yōu)和Full GC
.在對(duì)JVM調(diào)優(yōu)的過(guò)程中,很大一部分工作就是對(duì)于Full GC的調(diào)節(jié)。有如下原因可能導(dǎo)致Full GC:
1.年老代(Tenured)被寫(xiě)滿
2.持久代(Perm)被寫(xiě)滿
3.System.gc()被顯式調(diào)用(程序建議GC啟動(dòng),不是調(diào)用GC)
4.上一次GC之后Heap的各域分配策略動(dòng)態(tài)變化
3.this
· 對(duì)象創(chuàng)建的過(guò)程和this的本質(zhì)
構(gòu)造方法是創(chuàng)建Java對(duì)象的重要途徑,通過(guò)new關(guān)鍵字調(diào)用構(gòu)造器時(shí),構(gòu)造器也確實(shí)返回該類的對(duì)象,但這個(gè)對(duì)象并不是完全由構(gòu)造器負(fù)責(zé)創(chuàng)建。創(chuàng)建一個(gè)對(duì)象分為如下四步:
1. 分配對(duì)象空間,并將對(duì)象成員變量初始化為0或空
2. 執(zhí)行屬性值的顯式初始化
3. 執(zhí)行構(gòu)造方法
4. 返回對(duì)象的地址給相關(guān)的變量
this最常的用法:
1. ?在程序中產(chǎn)生二義性之處,應(yīng)使用this來(lái)指明當(dāng)前對(duì)象;普通方法中,this總是指向調(diào)用該方法的對(duì)象。構(gòu)造方法中,this總是指向正要初始化的對(duì)象。
2. 使用this關(guān)鍵字調(diào)用重載的構(gòu)造方法,避免相同的初始化代碼。但只能在構(gòu)造方法中用,并且必須位于構(gòu)造方法的第一句。
3. this不能用于static方法中。
?TestThis(int?a,?int?b){
? ? this.a=a;
? ? this.b=b;
}
TestThis(int?a,?int?b,?int?c)?{
????????this(a,?b);?//?調(diào)用帶參的構(gòu)造方法,并且必須位于第一行!
????????this.c?=?c;
????}
this的本質(zhì)就是“創(chuàng)建好的對(duì)象的地址”! 由于在構(gòu)造方法調(diào)用前,對(duì)象已經(jīng)創(chuàng)建。因此,在構(gòu)造方法中也可以使用this代表“當(dāng)前對(duì)象”?
4.static 關(guān)鍵字
在類中,用static聲明的成員變量為靜態(tài)成員變量,也稱為類變量。 類變量的生命周期和類相同,在整個(gè)應(yīng)用程序執(zhí)行期間都有效。它有如下特點(diǎn):
1. 為該類的公用變量,屬于類,被該類的所有實(shí)例共享,在類被載入時(shí)被顯式初始化。
2. 對(duì)于該類的所有對(duì)象來(lái)說(shuō),static成員變量只有一份。被該類的所有對(duì)象共享!!
3. 一般用“類名.類屬性/方法”來(lái)調(diào)用。(也可以通過(guò)對(duì)象引用或類名(不需要實(shí)例化)訪問(wèn)靜態(tài)成員。)
4. 在static方法中不可直接訪問(wèn)非static的成員。
核心要點(diǎn):
?? ??????static修飾的成員變量和方法,從屬于類。
? ? ? ? ?普通變量和方法從屬于對(duì)象的。
public?class?User2?{
????int?id;?//?id
????String?name;?//?賬戶名
????String?pwd;?//?密碼
? ?static?String?company?=?"北京尚學(xué)堂";?//?公司名稱
????public?User2(int?id,?String?name)?{
????????this.id?=?id;
????????this.name?=?name;
????}
????public?void?login()?{
????????printCompany();//非靜態(tài)可以調(diào)用靜態(tài)的(因?yàn)轭愋畔⑹窍燃虞d的java User2 就會(huì)去加載類信息,而沒(méi)new的時(shí)候是不會(huì)去創(chuàng)建對(duì)象的,所以靜態(tài)方法里不能調(diào)用非靜態(tài)信息。?)
????????System.out.println(company);?
????????System.out.println("登錄:"?+?name);
????}
????public?static?void?printCompany()?{
//?????????login();//調(diào)用非靜態(tài)成員,編譯就會(huì)報(bào)錯(cuò)
????????System.out.println(company);
????}
????public?static?void?main(String[]?args)?{
????????User2?u?=?new?User2(101,?"高小七");
????????User2.printCompany();
????????User2.company?=?"北京阿里爺爺";
????????User2.printCompany();
????}
}
下面內(nèi)存圖片解釋為什么在靜態(tài)方法中不能調(diào)用非靜態(tài)方法: