java 类爆炸_Java 封装与类
一、面向?qū)ο缶幊?/p>
面向?qū)ο缶幊倘筇匦?#xff1a;封裝、繼承和多態(tài)。
類(lèi)是實(shí)現(xiàn)封裝的手段,是面向?qū)ο缶幊痰幕締卧?/p>
封裝隱藏了類(lèi)的內(nèi)部實(shí)現(xiàn)細(xì)節(jié),暴露給外界可控的操作,提高數(shù)據(jù)的完整性和安全性,提高模塊的可重用性和開(kāi)發(fā)效率,降低開(kāi)發(fā)的復(fù)雜性。
從面向?qū)ο蟪绦蛟O(shè)計(jì)方法的角度看,程序中所有的東西都是對(duì)象,而程序是對(duì)象的組合,對(duì)象間通過(guò)消息傳遞實(shí)現(xiàn)協(xié)作。
二、類(lèi)
類(lèi)是Java程序設(shè)計(jì)的核心概念和基本單元。
類(lèi)是對(duì)一類(lèi)事物的特征的描述,是抽象后的描述;對(duì)象是一個(gè)實(shí)例。
1、Java沒(méi)有全局變量,只有:
靜態(tài)變量:隸屬于類(lèi)
實(shí)例變量:類(lèi)體中定義,類(lèi)的屬性,隸屬于對(duì)象。
局部變量:形參、方法內(nèi)定義或代碼塊中定義,隸屬于方法。
2、成員修飾符——public、private、protected、default
作用:實(shí)現(xiàn)訪問(wèn)權(quán)限控制。
public:被public修飾的成員,可以在任何一個(gè)類(lèi)中被調(diào)用。
private:除了本類(lèi)的方法能夠調(diào)用私有成員(方法、屬性),其他任何類(lèi)都不能直接訪問(wèn)私有成員。
所有修飾符都能修飾數(shù)據(jù)成員、方法成員和構(gòu)造方法;只有public和default能修飾類(lèi)(外部類(lèi))。
3、方法重載
(1)方法名相同
(2)方法的參數(shù)簽名不相同(參數(shù)類(lèi)型、個(gè)數(shù)、順序)。
(3)方法的返回類(lèi)型可以不同,方法的修飾符也可以不同
三、對(duì)象
3.1 構(gòu)造方法
與類(lèi)名同名,不返回任何數(shù)據(jù)類(lèi)型(實(shí)際上沒(méi)有返回任何東西),沒(méi)有void,不能有任何非訪問(wèn)性質(zhì)的修飾符。
類(lèi)中可以有多個(gè)構(gòu)造方法——應(yīng)用了方法重載,每個(gè)構(gòu)造方法在被調(diào)用后將在堆內(nèi)存中創(chuàng)建一個(gè)對(duì)象然后向調(diào)用者返回一個(gè)該對(duì)象的引用(這里的引用,是指對(duì)象在堆內(nèi)存空間中的首地址)
this,表示一個(gè)對(duì)象引用,其值指向正在執(zhí)行方法的對(duì)象;
特別地,構(gòu)造方法中,通過(guò)this調(diào)用其他構(gòu)造方法時(shí),必須放在第一行;
構(gòu)造方法只能通過(guò)this調(diào)用一次其他構(gòu)造方法;
關(guān)鍵字new的作用是(調(diào)用)一個(gè)構(gòu)造函數(shù),為對(duì)象分配內(nèi)存空間,返回這塊內(nèi)存的引用。
如果沒(méi)有顯示定義構(gòu)造方法,類(lèi)將會(huì)隱式定義一個(gè)默認(rèn)情況下不接受任何參數(shù)的構(gòu)造函數(shù)并將所有實(shí)例變量初始化為默認(rèn)值。
原始數(shù)字類(lèi)型的實(shí)例變量默認(rèn)值為0,布爾類(lèi)型變量為false,引用類(lèi)型變量為null。
只要沒(méi)有將類(lèi)中的變量進(jìn)行初始化,它就會(huì)有默認(rèn)值。但是final變量可以把初始化放到構(gòu)造方法中進(jìn)行,而static final必須在聲明時(shí)就進(jìn)行初始化。
3.2 創(chuàng)建對(duì)象
創(chuàng)建對(duì)象的過(guò)程即類(lèi)實(shí)例化的過(guò)程,包括類(lèi)的加載、對(duì)象內(nèi)存分配和變量初始化。
(1)new顯示創(chuàng)建
Cat ketty=new Cat();
new操作符,在內(nèi)存中為對(duì)象開(kāi)辟空間,它在堆內(nèi)存上為對(duì)象開(kāi)辟空間,動(dòng)態(tài)地分配內(nèi)存(主要存放對(duì)象的實(shí)例變量)。“動(dòng)態(tài)分配“的意思是在程序運(yùn)行時(shí)內(nèi)存才會(huì)被分配,這樣你可以創(chuàng)建任意數(shù)量的對(duì)象。
ketty稱(chēng)為對(duì)象引用,表示可以指向一個(gè)Cat類(lèi)型的實(shí)例。ketty位于棧中。
等號(hào)賦值,將右邊在堆中創(chuàng)建的對(duì)象的內(nèi)存空間的首地址賦予了對(duì)象的引用變量ketty。
(2)調(diào)用java.lang.Class類(lèi)的newInstance()方法
Java中的任何類(lèi)都包含有有一個(gè)Class類(lèi),它描述該類(lèi)的元數(shù)據(jù)。通過(guò)調(diào)用Class類(lèi)的類(lèi)方法,創(chuàng)建對(duì)象:
Cat ketty=Cat.getClass().newInstance();
或者使用動(dòng)態(tài)類(lèi)加載語(yǔ)句(需存在相應(yīng)的.class文件即可)創(chuàng)建:
Cat ketty=(Cat) Class.forName("Cat").newInstance();
通過(guò)類(lèi)加載器方式創(chuàng)建類(lèi)必須保證被創(chuàng)建的類(lèi)在搜索路徑中存在相應(yīng)的.class文件。
newInstance()方法創(chuàng)建對(duì)象實(shí)例會(huì)調(diào)用無(wú)參構(gòu)造函數(shù),所以必須確保類(lèi)中存在無(wú)參數(shù)的構(gòu)造函數(shù),否則會(huì)有異常。
private修飾構(gòu)造方法:
有時(shí)希望控制對(duì)象的生成或者阻止直接通過(guò)new在類(lèi)的外部生成類(lèi)的實(shí)例,這時(shí)用private修飾構(gòu)造方法。單例設(shè)計(jì)模式就是通過(guò)此方法實(shí)現(xiàn)只創(chuàng)建一個(gè)對(duì)象的實(shí)例。
public classSingleton{private static Singleton instance=null;privateSingleton(){
System.out.println("private singleton is caled!")
}public staticSingleton getInstance(){if(instance==null)
instance=newSingleton();returninstance;
}
}
3.3 使用對(duì)象
適用對(duì)象必須通過(guò)對(duì)象的引用,像c中的指針,但不能像指針那樣直接修改引用值,而是只能通過(guò)它執(zhí)行對(duì)象操作。
將一個(gè)對(duì)象的引用賦值給另一個(gè)引用時(shí),實(shí)際上復(fù)制的是對(duì)象的引用地址,結(jié)果是兩個(gè)引用指向同一個(gè)對(duì)象。
3.4 Java的方法的參數(shù)傳遞機(jī)制——值傳遞
當(dāng)傳遞一個(gè)參數(shù)時(shí),方法獲得該參數(shù)的一個(gè)副本。
事實(shí)上,傳遞的參數(shù)會(huì)有倆種:基本類(lèi)型的變量和對(duì)象的引用變量。
基本類(lèi)型的變量,意味著變量值本身被復(fù)制,并傳遞給方法,因此,方法中對(duì)變量的修改不會(huì)影響原變量;
對(duì)象的引用變量,即對(duì)象的引用值(堆中的首地址)被復(fù)制,傳遞給方法。方法中的操作可以影響對(duì)象。
3.5 垃圾回收機(jī)制
一個(gè)對(duì)象不再被使用,應(yīng)該回收該對(duì)象占用的內(nèi)存空間以及資源,從而提高內(nèi)存利用率。
Java中,內(nèi)存的回收由垃圾回收器(Garbage Collection)自動(dòng)處理。處理流程:
查看堆內(nèi)存,區(qū)分出正在使用的對(duì)象和未使用的對(duì)象;
刪除已經(jīng)廢棄的對(duì)象;
3.6 如何區(qū)分一個(gè)對(duì)象是否任然會(huì)被使用呢?
判斷標(biāo)準(zhǔn)——程序持有一個(gè)指向?qū)ο蟮囊?#xff1b;若一個(gè)對(duì)象,不被程序的任何部分持有引用,則判定它的內(nèi)存是可以被回收的。
GC是通過(guò)JVM一個(gè)后臺(tái)的工作線程來(lái)完成,它周期性地掃描堆內(nèi)存來(lái)發(fā)現(xiàn)程序不再使用的對(duì)象。為了判斷對(duì)象是否可以被釋放,需要引用計(jì)數(shù)和對(duì)象引用遍歷。引用技術(shù)記錄了對(duì)特定對(duì)象的所有引用數(shù),這意味著,當(dāng)應(yīng)用程序創(chuàng)建引用或者引用已經(jīng)超出聲明周期時(shí),JVM必須適當(dāng)?shù)卦鰷p引用計(jì)數(shù)。當(dāng)對(duì)象的引用數(shù)為0時(shí),便可以進(jìn)行垃圾收集。
3.7 手動(dòng)啟動(dòng)GC
垃圾回收器是JVM自動(dòng)啟動(dòng)的,它不受程序代碼的控制,其具體執(zhí)行的時(shí)間也不確定,但是開(kāi)發(fā)者可以利用System.gc()手動(dòng)強(qiáng)制啟動(dòng)垃圾回收氣銷(xiāo)毀無(wú)用對(duì)象。
GC機(jī)制還提供了finalize()方法,用于釋放不是通過(guò)new操作符創(chuàng)建的對(duì)象空間。這種情況一般發(fā)生在使用“本地方法(Native Interface)”的情況下,本地方法是一種在Java中調(diào)用非Java代碼的方式。
finalize()方法會(huì)在GC釋放對(duì)象時(shí)被執(zhí)行,即要是我們手動(dòng)調(diào)用了System.gc(),finalize()也會(huì)一起執(zhí)行。
四、實(shí)例變量和類(lèi)變量
4.1 static靜態(tài)變量(類(lèi)變量)
所有對(duì)象共享類(lèi)變量。
程序執(zhí)行時(shí),類(lèi)的字節(jié)碼被加載到內(nèi)存,如果該類(lèi)沒(méi)有創(chuàng)建對(duì)象,類(lèi)的實(shí)例成員變量不會(huì)被分配內(nèi)存。類(lèi)中聲明的類(lèi)變量在該類(lèi)被加載到內(nèi)存時(shí),就已經(jīng)被分配了相應(yīng)的內(nèi)存空間,直到程序退出運(yùn)行才釋放所占用的內(nèi)存。而如果該類(lèi)沒(méi)有被創(chuàng)建對(duì)象,類(lèi)的實(shí)例成員變量不會(huì)被分配內(nèi)存。
從數(shù)據(jù)操作的角度來(lái)看,實(shí)例方法既能對(duì)類(lèi)變量進(jìn)行操作,又能對(duì)實(shí)例變量進(jìn)行操作;而類(lèi)方法只能對(duì)類(lèi)變量進(jìn)行操作。
實(shí)例變量子在申明時(shí)如果沒(méi)有被賦予初值,將被編譯器初始化為NULL(引用類(lèi)型),0,或者false,字符變量默認(rèn)是空。
類(lèi)變量在類(lèi)的初始化之前初始化,無(wú)論類(lèi)的實(shí)例被創(chuàng)建多少個(gè),類(lèi)變量只在初始化時(shí)被分配一次內(nèi)存空間。
不同的對(duì)象將被分配到不同的堆內(nèi)存空間
4.2?靜態(tài)代碼塊和非靜態(tài)代碼塊
static {…}為靜態(tài)代碼塊,{…}直接括起來(lái)的為非靜態(tài)。
凡是static修飾的,都將最先在類(lèi)被加載時(shí),按排列的位置執(zhí)行(當(dāng)然你不能在靜態(tài)變量還沒(méi)有初始化前就使用它,即你的靜態(tài)代碼塊如果在靜態(tài)變量的聲明之前,就無(wú)法使用,但是可以直接初始化它);
非靜態(tài)代碼塊在類(lèi)初始化創(chuàng)建實(shí)例時(shí),將會(huì)被提取到類(lèi)的構(gòu)造器中執(zhí)行,而且,非靜態(tài)代碼塊會(huì)比構(gòu)造器中的代碼塊先執(zhí)行。
public classStaticDemo{static{
name="static-block-1";
System.out.println("static block 1 is over!");
}public static String name="Fancy";private String mail="myEmail";static{
System.out.println(name);
name="static-block-2";
System.out.println("static block 2 is over!");
}publicStaticDemo(){
mail="110@qq.com";
System.out.println("Constructor has been excuted and the name is "+name);
}static{
System.out.println(name);
name="static-block-3";
System.out.println("static block 3 is over!");
}
{
mail="119@qq.com";
System.out.println("Non-static block has been excuted");
}public voidsetName(String name){this.name=name;
System.out.println("SetName is called.");
}public static voidmain(String[] args) {
StaticDemo staticDemo=newStaticDemo();
staticDemo.setName("Jay");
}
}//output:
static block 1 is over!Fancystatic block 2 is over!
static-block-2
static block 3 is over!Non-staticblock has been excuted
Constructor has been excuted and the name isstatic-block-3SetName is called.
4.3 不可變對(duì)象
一旦創(chuàng)建就不能被更改。(沒(méi)有給外界提供可以修改的操作而已,并沒(méi)有多特別)
它的類(lèi)為不可變類(lèi),“不可變”是一種很好的性質(zhì),它使得對(duì)象的行為是可預(yù)測(cè)的。它可以被其它對(duì)象隨意引用,而不用擔(dān)心不可變對(duì)象在某個(gè)時(shí)刻被修改。
優(yōu)點(diǎn):
Java中的所有不可變對(duì)象都是線程安全的。
構(gòu)造、測(cè)試和使用都很簡(jiǎn)單;
當(dāng)用作其它類(lèi)的屬性時(shí)不需要被保護(hù)性復(fù)制;
可以很好地用作Map集合和Set集合的元素;
編寫(xiě)一個(gè)不可變類(lèi),就不要提供任何可以修改對(duì)象狀態(tài)的方法。
總結(jié)
以上是生活随笔為你收集整理的java 类爆炸_Java 封装与类的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java kettle6_Java调用K
- 下一篇: 存现金的会计分录