- Java組件設(shè)計(jì)
- 孔德生編著
- 1813字
- 2018-12-29 19:21:04
3.1 Java語(yǔ)法深入講解
本節(jié)對(duì)Java語(yǔ)法中一些高級(jí)主題進(jìn)行講解。
3.1.1 static
1.static變量
本質(zhì)上講,static關(guān)鍵字聲明了一個(gè)全局變量。
盡管Java是一門純面向?qū)ο蟮恼Z(yǔ)言,語(yǔ)言規(guī)范中沒有全局變量這種說法,但static聲明的變量,從本質(zhì)上就等同于C或C++語(yǔ)言中的全局變量。整個(gè)應(yīng)用程序只有一個(gè)變量實(shí)例,任何對(duì)static變量進(jìn)行的更改,在程序的其他地方都可見。
舉個(gè)例子如下:
public class StaticExample {
public static int counter;
}
counter是個(gè)整型變量,前面用static關(guān)鍵字修飾后,就變成了一個(gè)全局變量,在程序的代碼執(zhí)行之前,這個(gè)counter變量就已經(jīng)存在于內(nèi)存中了,而且是唯一的實(shí)例。
counter靜態(tài)變量是在StaticExample類中聲明的,但實(shí)際上counter變量是獨(dú)立于StaticExample的任何實(shí)例的。也就是說,程序沒有創(chuàng)建任何StaticExample實(shí)例時(shí), counter已經(jīng)存在。程序創(chuàng)建100個(gè)StaticExample實(shí)例時(shí),couner在內(nèi)存中仍然是一個(gè),而不是100個(gè)。當(dāng)程序中創(chuàng)建的StaticExample類的實(shí)例都被虛擬機(jī)垃圾回收了, counter還存在。因此靜態(tài)變量的生命周期,可以認(rèn)為程序的第一行代碼執(zhí)行之前,就已經(jīng)在內(nèi)存中準(zhǔn)備好,在程序的最后一行代碼執(zhí)行完畢,靜態(tài)變量還存在于內(nèi)存中。靜態(tài)變量獨(dú)立于任何對(duì)象,包括聲明靜態(tài)變量的類實(shí)例對(duì)象。
對(duì)簡(jiǎn)單類型是這樣,對(duì)復(fù)雜類型(對(duì)象類型)也是這樣。
靜態(tài)變量的這種特性,經(jīng)常被用在單實(shí)例的類實(shí)現(xiàn)中,例子如下:
public class Logger { // 構(gòu)造函數(shù)聲明為private, 這樣就不能在類的外部用new 來創(chuàng)建對(duì)象 private Logger() {} private static Logger logger=null; // 單實(shí)例 // 暴露給外界調(diào)用的方法 public static Logger getLogger() { if(null==logger){ // 判斷靜態(tài)實(shí)例是否初始化,如沒有就創(chuàng)建 logger=new Logger(); } return logger; // 返回全局唯一的實(shí)例 } //…… 其他方法聲明 }
2.static方法
如果一個(gè)方法,僅依賴方法的傳入?yún)?shù)、其他static變量,則此方法不依賴于聲明方法的類實(shí)例,應(yīng)該聲明為static。表示此方法是類方法,而非實(shí)例方法。例子如下:
public class ConvertUtil {
public static int toInt(String s) { return Integer.parseInt(s); } }
toint方法的實(shí)現(xiàn),僅依賴于方法傳入的參數(shù)s,不依賴ConvertUtil對(duì)象的成員變量,因此toint方法是個(gè)類方法,不是個(gè)實(shí)例方法,因此用static來修飾toint方法的聲明。這樣,調(diào)用者調(diào)用時(shí)的代碼就像下面這樣:
int iValue = ConvertUtil.toInt(str);
如果不用static修飾,則調(diào)用者的代碼就需要修改為如下:
ConvertUtil util = new ConvertUtil(); int iValue = util.toInt(str);
但實(shí)際上,toint方法根本就不需要?jiǎng)?chuàng)建一個(gè)ConvertUtil類的實(shí)例,創(chuàng)建這個(gè)對(duì)象是個(gè)浪費(fèi)。
組件設(shè)計(jì)中,常用的工具類方法,基本都是static方式聲明的。
3.static類
一個(gè)普通的Java類聲明,用static修飾,是非法的,編譯器會(huì)提示出錯(cuò)。這一點(diǎn),與C++的靜態(tài)類的概念是完全不同的。在C++中,一個(gè)類的聲明用static修飾,則這個(gè)類中的所有成員變量和成員函數(shù)都是靜態(tài)方法,獨(dú)立于對(duì)象存在。
對(duì)于嵌套類的聲明,可以用static修飾,但這有另外的含義,在后續(xù)的嵌套類中進(jìn)行講解。
3.1.2 嵌套類
一個(gè)類的聲明,是在另外一個(gè)類中,這種在類中聲明的類叫嵌套類,也叫類中類、內(nèi)部類。例子如下:
public class Outer { private String outerId;
private Inner inner = new Inner(); public String getId() { // 訪問內(nèi)部類的私有成員 return outerId + "-" + inner.innerId; } public void setId(String id) { String[] strArray = id.split("-"); outerId = strArray[0]; inner.setId(strArray[1]); // 調(diào)用內(nèi)部類的私有方法 } private void printStr(String str) { System.out.println(str); } // 內(nèi)部類定義 public class Inner { private String innerId; private String getId() { return innerId; } private void setId(String id) { innerId = id; } protected void printId() { String str = "outerId=" + outerId + ", innerId=" + innerId; // 訪問外部類的私有成員 printStr(str); // 訪問外部類的私有方法 } } }
總結(jié)如下:
(1)內(nèi)部類可以訪問外部類的任何成員變量,包括外部類實(shí)例的私有成員變量。
(2)內(nèi)部類可以調(diào)用外部類的任何成員函數(shù),包括外部類實(shí)例的私有成員函數(shù)。
(3)外部類可以訪問內(nèi)部類的任何成員變量,包括內(nèi)部類實(shí)例的私有成員變量。
(4)外部類可以調(diào)用內(nèi)部類的任何成員函數(shù),包括內(nèi)部類實(shí)例的私有成員函數(shù)。
因此,對(duì)于內(nèi)部類的成員變量和成員函數(shù),用private, protected, public, package修飾,就如同沒有這些修飾詞一樣。
另外,內(nèi)部類是不能獨(dú)立于外部類而單獨(dú)存在的,對(duì)象構(gòu)造的順序是由外向內(nèi),先生成外部類,然后生成內(nèi)部類。
3.1.3 靜態(tài)嵌套類
嵌套類,在類聲明的時(shí)候用static修飾,就成了靜態(tài)嵌套類。靜態(tài)嵌套類與普通嵌套類是完全不同的。這里,static的唯一作用,就相當(dāng)于一個(gè)分隔符,將內(nèi)部類和外部類隔離開來,使內(nèi)部類獨(dú)立于外部類單獨(dú)存在。也就是說,內(nèi)部類對(duì)外部類沒有任何的依賴關(guān)系。而普通的內(nèi)部類,是必須依賴于外部類而存在的。
因此,外部類與靜態(tài)內(nèi)部類之間的關(guān)系,就和兩個(gè)獨(dú)立的類之間的關(guān)系相同,二者之間互相訪問,與兩個(gè)獨(dú)立類之間的訪問規(guī)則相同。因此,用private, protected, public, package修飾,將直接影響可訪問性。示例如下:
public class OuterClass { private String outerId; private StaticInner inner = new StaticInner(); public String getId() { //return outerId+"-"+inner.innerId(); // 私有成員,不允許訪問 return outerId+"-"+inner.getInnerId();// 公有方法,可以訪問 } public void setId(String id) { String[] strArray = id.split("-"); outerId = strArray[0]; inner.setInnerId(strArray[1]); // 公有方法,可以訪問
} private void printStr(String str) { System.out.println(str); } public static class StaticInner { private String innerId; public String getInnerId() { return innerId; } public void setInnerId(String innerId) { this.innerId = innerId; } public void printId() { // 無法訪問外部類的私有成員 // String str = "outerId=" + outerId + ", innerId=" + innerId; //printStr(str); // 無法訪問外部類的私有方法 OuterClass outer = new OuterClass(); outer.printStr(innerId); // 同一package中,可以訪問私有方法 } } }
- JavaScript實(shí)例自學(xué)手冊(cè)
- 高性能混合信號(hào)ARM:ADuC7xxx原理與應(yīng)用開發(fā)
- R Data Mining
- Dreamweaver CS3網(wǎng)頁(yè)設(shè)計(jì)50例
- 教父母學(xué)會(huì)上網(wǎng)
- 快學(xué)Flash動(dòng)畫百例
- 自動(dòng)化控制工程設(shè)計(jì)
- Apache Spark Deep Learning Cookbook
- 系統(tǒng)安裝與重裝
- 精通數(shù)據(jù)科學(xué)算法
- 愛犯錯(cuò)的智能體
- 工業(yè)機(jī)器人安裝與調(diào)試
- Google SketchUp for Game Design:Beginner's Guide
- DevOps Bootcamp
- 格蠹匯編