渝北網(wǎng)站建設(shè)鄭州seo優(yōu)化外包公司
書接上回
類與對(duì)象
static關(guān)鍵字
static的作用:
- 修飾一個(gè)屬性:聲明為static的變量實(shí)質(zhì)上就是一個(gè)全局變量,其生命周期為從類被加載開始一直到程序結(jié)束;
- 修飾方法:無(wú)須本類的對(duì)象也可以調(diào)用該方法;
- 修飾一個(gè)類:該類必須是內(nèi)部類(后說(shuō));
靜態(tài)類與變量通過類名直接調(diào)用:類名.靜態(tài)變量/靜態(tài)方法。注意,非靜態(tài)方法中可以調(diào)用靜態(tài)的變量和方法,而靜態(tài)方法中只能調(diào)用靜態(tài)的變量和方法,不能調(diào)用非靜態(tài)的變量和方法。
public class Test{public static void main(String[] args) {House h;//聲明一個(gè)類的變量h = new House();//創(chuàng)建實(shí)例對(duì)象h.kind = "別墅";h.Print();//非靜態(tài)方法的調(diào)用需要有h這個(gè)對(duì)象House.Smile();//靜態(tài)類直接調(diào)用System.out.println(House.Count);//變量的調(diào)用也一樣}
}
public class House{String kind = "未知";static int Count = 3;public void Ptint(){System.out.println(kind + Count +"棟");}public static void Smile(){System.out.println("哈哈,被騙了");}
}
靜態(tài)方法限制:
- 僅能調(diào)用其他static方法;
- 只能訪問static數(shù)據(jù);
- 不能以任何方式引用this和super;
因?yàn)閟tatic的限制,所以我們?cè)俣x他的時(shí)候最好確定之后他是否是所有對(duì)象共同的屬性或方法在將其定義為靜態(tài)。
值傳遞與引用傳遞
有一道非常經(jīng)典的面試題目:
public class Test {public static void main(String[] args) {Integer a = 1;Integer b = 2;System.out.println("a 和 b 的原始的值:"+a+" "+b);swap(a,b);System.out.println("a 和 b 的現(xiàn)在的值:"+a+" "+b);}private static void swap(Integer a, Integer b) {// 交換a與b的值}
實(shí)現(xiàn)變量的交換非常簡(jiǎn)單,前面已經(jīng)學(xué)習(xí)過了三種交換方法,直接帶入最簡(jiǎn)單的:
private static void swap(Integer a, Integer b) {// 交換a與b的值int c;c = a;a = b;b = c;}
完成后最后的結(jié)果卻是錯(cuò)的,這是因?yàn)槌绦蛑兄唤粨Q了形參的值,而實(shí)參卻沒有絲毫變化。
形參 :就是形式參數(shù),用于定義方法的時(shí)候使用的參數(shù),是用來(lái)接收調(diào)用者傳遞的參數(shù)的。 形參只有在方法被調(diào)用的時(shí)候,虛擬機(jī)才會(huì)分配內(nèi)存單元,在方法調(diào)用結(jié)束之后便會(huì)釋放所分配的內(nèi)存單元。 因此,形參只在方法內(nèi)部有效,所以針對(duì)引用對(duì)象的改動(dòng)也無(wú)法影響到方法外。
實(shí)參 :就是實(shí)際參數(shù),用于調(diào)用時(shí)傳遞給方法的參數(shù)。實(shí)參在傳遞給別的方法之前是要被預(yù)先賦值的。 在本例中 swap 方法中的a, b 就是形參,傳遞給 swap 方法的 a,b 就是實(shí)參。
值傳遞:只能把實(shí)參傳遞給形參,而不能把形參的值反向作用到實(shí)參上。在函數(shù)調(diào)用過程中,形參的值發(fā)生改變,而實(shí)參的值不會(huì)發(fā)生改變。
在上題中,實(shí)際內(nèi)存情況:
引用傳遞:是將實(shí)參引用的地址傳遞給了形參,所以任何發(fā)生在形參上的改變也會(huì)發(fā)生在實(shí)參變量上。
在第一個(gè)程序中h.kind = "別墅";
這就是引用傳遞:
內(nèi)存結(jié)構(gòu)
.class:java程序編譯后產(chǎn)生的編譯文件;
類加載器:加載.class文件 ;
方法區(qū):各個(gè)線程共享的內(nèi)存區(qū)域,它用于存儲(chǔ)已被虛擬機(jī)加載的類信息、常量、靜態(tài)變量、即時(shí)編譯器編譯后的代碼等數(shù)據(jù);
棧內(nèi)存: 在棧內(nèi)存中保存的是堆內(nèi)存空間的訪問地址,或者說(shuō)棧中的變量指向堆內(nèi)存中的變量(Java中的指針);
堆內(nèi)存:堆內(nèi)存用來(lái)存放由new創(chuàng)建的對(duì)象實(shí)例和數(shù)組;
本地方法棧:存儲(chǔ)本地方法,比如c語(yǔ)言棧。
程序計(jì)數(shù)器:可以看做是當(dāng)前線程所執(zhí)行的字節(jié)碼的行號(hào)指示器,分支、循環(huán)、跳轉(zhuǎn)、異常處理、線程恢復(fù)等基礎(chǔ)功能都要依賴這個(gè)計(jì)數(shù)器來(lái)完成。
代碼塊
用大括號(hào)裹起來(lái)的代碼:
- 普通代碼塊:在方法中的寫的代碼塊;
- 構(gòu)造塊:在類中定義的代碼塊,在創(chuàng)造對(duì)象時(shí)被調(diào)用,優(yōu)于構(gòu)造方法;
- 靜態(tài)代碼塊:在類中是使用static聲明的代碼塊,在第一次被調(diào)用(創(chuàng)建對(duì)象)時(shí)被調(diào)用,只會(huì)執(zhí)行一次,優(yōu)于構(gòu)造塊;
- 同步代碼塊:多線行程中介紹;
public class Test{public static void main(String[] args) {House h1 = new House();House h2 = new House();House h = null;}
}
public class House{public House(){System.out.println("構(gòu)造方法/n--------------");}{System.out.println("構(gòu)造塊House/n---------");}public static void Smile(){{String info = "普通代碼塊smile/n-----------";System.out.println(info); }}static {String info = "靜態(tài)代碼塊smile/n-----------";}
}