為什么會(huì)有這篇文章呢,是因?yàn)槲以趯W(xué)習(xí)各種框架的時(shí)候發(fā)現(xiàn)很多框架都用到了這些內(nèi)部類的小技巧,雖然我平時(shí)寫代碼的時(shí)候基本不用,但是看別人代碼的話至少要了解基本知識(shí)吧,另外到底內(nèi)部類應(yīng)該應(yīng)用在哪些場(chǎng)合,我并不是很清楚,留下一些值得思考的問題作為記錄,說不定以后能自己來填。于是就會(huì)有這篇文章啦。
常規(guī)使用方法我也不想介紹,網(wǎng)上一大把,我就說說比較容易錯(cuò)的,值得注意的地方。
注意這篇文章只是分享一下我對(duì)內(nèi)部類的一些研究與困惑吧,說不定對(duì)大家有幫助,說不定能引導(dǎo)大家一起思考學(xué)習(xí)。Java語法知識(shí)其實(shí)是很復(fù)雜很容易錯(cuò)的,特別是在細(xì)節(jié)方面。所以我的觀點(diǎn)可能會(huì)有各種錯(cuò)誤。
另外我的JDK版本是1.7。JDK1.8的版本貌似對(duì)內(nèi)部類的規(guī)則有一些修改,所以請(qǐng)大家注意。
非靜態(tài)非匿名內(nèi)部類不能擁有static成員網(wǎng)上大部分文章的說法大致是這樣的,就是告訴你這種內(nèi)部類不能擁有static的方法,屬性。其實(shí)這句話有那么點(diǎn)小問題。非靜態(tài)內(nèi)部類也可以擁有static的屬性的(static區(qū)塊不行),但是要求這個(gè)static屬性必須是常量,這個(gè)地方經(jīng)過我的研究,我覺得和 “調(diào)用類的static屬性,但卻不會(huì)初始化這個(gè)類的static區(qū)塊和其他static變量” 有點(diǎn)相似。什么意思?就是說
1 class Outter{2 class Inner{3 final static int a = 9; 4 }5 }這樣是沒有編譯錯(cuò)誤的。要求靜態(tài)變量a必須是final類型的,且是基本類型,且是字面值
1 class Outter{2 class Inner{3 final static int a = get(); 4 }5 6 static int get(){7 return 1;8 }9 }這樣就會(huì)報(bào)錯(cuò),因?yàn)閍不是字面值。
這里我想請(qǐng)大家看一下我的另外一篇學(xué)習(xí)記錄,這種變量是不會(huì)觸發(fā)類初始化的。
地址:http://m.survivalescaperooms.com/abcwt112/p/4567332.html分析標(biāo)題下面的第二小點(diǎn)。
當(dāng)然,這種字面值貌似沒什么卵用啊。。。。所以說這種內(nèi)部類不能有static成員大致上好像也算對(duì)吧。。
為什么不能擁有static成員?
我覺得道理是這樣的(個(gè)人理解)。非靜態(tài)的內(nèi)部類是和普通成員一樣的,是隸屬于外部類對(duì)象的,創(chuàng)建這種內(nèi)部類對(duì)象需要先創(chuàng)建外部類對(duì)象。也就是說這種內(nèi)部類是不能單獨(dú)于外部類對(duì)象存在的。這個(gè)道理大家都明白,一個(gè)成員變量怎么能脫離于類的對(duì)象獨(dú)立存在呢。那假設(shè)這種內(nèi)部類可以擁有static的屬性,比如static int a = 1;那這個(gè)a數(shù)據(jù)存在哪里呢?根據(jù)前面的分析,應(yīng)該是存在于分配給外部類對(duì)象擁有的內(nèi)存中的,那么等外部類對(duì)象唄銷毀以后,這個(gè)a分配的內(nèi)存也會(huì)被銷毀。這樣的話修改這個(gè)a毫無意義,因?yàn)槊看味际侵匦路峙鋬?nèi)存,每次值都是1。所以這個(gè)static沒什么用,并不是全局的。
這個(gè)問題我是這么理解的。我覺得等我看完JVM虛擬機(jī)(我覺得有可能final static int與static int變量值存的地方可能不一樣)或者學(xué)習(xí)匯編(可以觀察數(shù)據(jù)是怎么存儲(chǔ)的)以后再看它可能會(huì)有更深的理解。
靜態(tài)內(nèi)部類只能調(diào)用外部類的靜態(tài)方法與屬性這點(diǎn)蠻好理解,就像靜態(tài)方法main里不能調(diào)用非靜態(tài)的屬性,方法一樣。但是這并不代表靜態(tài)內(nèi)部類就不能定義 非靜態(tài)的方法和屬性。它不能調(diào)用外部類的非靜態(tài)的成員,但是卻可以在自己內(nèi)部定義。畢竟它是個(gè)類。。。。
1 public class StaticTest { 2 static int a = 9; 3 4 PRivate static class Inner{ 5 public static void main(String[] args) { 6 System.out.println(StaticTest.a); 7 } 8 9 public void doSomething(){10 11 }12 }13 public static class Inner2{14 }15 }這里代碼就沒有什么問題,能編譯通過(doSomething方法)。
用途(廢話)靜態(tài)內(nèi)部類是沒有指向外部類的引用的,所以說它和外部類并沒有什么關(guān)系,因此,即使沒有外部類的對(duì)象,也可以直接創(chuàng)建靜態(tài)內(nèi)部類的對(duì)象。但是我覺得如果是這樣使用的話,那完全沒必要把類弄成靜態(tài)內(nèi)部的,直接創(chuàng)建外部類一般的類就OK了。所以說靜態(tài)內(nèi)部類肯定有它自己獨(dú)特的作用。既然是個(gè)內(nèi)部類,我覺得應(yīng)該會(huì)聲明成private,不然還不如創(chuàng)建一個(gè)外部類呢。。。。那private static的class有啥用處呢?我也不清楚。。。現(xiàn)在我唯一覺得有用的地方就是可以把測(cè)試代碼main方法寫在里面。因?yàn)槭莗rivate的類,外接不能調(diào)用它,也就不能調(diào)用寫的main函數(shù)了。。但是如果只是測(cè)試的話可以使用junit test呀。。。不可能為了測(cè)試就專門搞這么一個(gè)語法。。。這點(diǎn)值得日后研究,等我代碼看得多了,說不定會(huì)有新體會(huì)。
我看Apache Shiro框架中的Ini類就有個(gè)靜態(tài)內(nèi)部類Section(被聲明為public類型),這個(gè)Section類獨(dú)立存在毫無意義,外部只需要用到Ini類就行了。但是又不能沒有,因?yàn)檫@個(gè)類地位其實(shí)和外部類Ini差不多,Ini是整個(gè)配置文件的抽象,Section是整個(gè)配置文件中每一小節(jié)的抽象。如果沒有這個(gè)類,可能Ini中可能需要定義大量的static方法和大量的map來做關(guān)聯(lián),這樣可能會(huì)很麻煩,所以shiro用到了這個(gè)靜態(tài)內(nèi)部類。具體內(nèi)容可以查看我的另外一篇文章,介紹了Ini類:http://m.survivalescaperooms.com/abcwt112/p/4641500.html
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注