1. 嵌套類
Java一個(gè)文件中除了有最頂層的類揩慕,在類內(nèi)部還可以定義新的類。之所以這樣設(shè)計(jì)有三點(diǎn)原因
- 能夠符合邏輯的編排那些只在一個(gè)地方用到的類
- 能夠提高封裝性,因?yàn)榍短最惪梢詫?duì)外隱藏但對(duì)內(nèi)訪問(wèn)外部類的成員
- 可以讓代碼更好閱讀和維護(hù)。峭沦。。逃糟。(這一點(diǎn)我覺(jué)得有待商榷)
嵌套類有多種形式吼鱼,第一種是內(nèi)部類,又分為靜態(tài)內(nèi)部類绰咽,和非靜態(tài)內(nèi)部類菇肃;第二種是本地類,出現(xiàn)在{}
中取募,一般是出現(xiàn)在函數(shù)琐谤、循環(huán)等;第三種是匿名類玩敏,用語(yǔ)句來(lái)表示斗忌。本地類和匿名類實(shí)際上是兩種特殊的內(nèi)部非靜態(tài)類。
2. 內(nèi)部類
內(nèi)部類需要了解聲明旺聚,實(shí)例化方式织阳,與外部類成員之間的關(guān)系,和序列化的一些知識(shí)點(diǎn)砰粹。
內(nèi)部類的訪問(wèn)控制修飾符與類中的成員修飾符一致唧躲,有四種,具體的訪問(wèn)控制范圍也是一致的。
//static inner class
class OuterClass{
modifier static class InnerClass{}
}
//non-static inner class
class OuterClass{
modifier class InnerClass{}
}
內(nèi)部類的數(shù)量有限制嗎惊窖?語(yǔ)言本身應(yīng)該是沒(méi)有限制的,但是在編譯過(guò)程中厘贼,會(huì)通過(guò)類決定class的文件名界酒,此時(shí)文件名長(zhǎng)度限制會(huì)對(duì)內(nèi)部類的層數(shù)有一定的限制,但對(duì)內(nèi)部類的數(shù)量會(huì)不會(huì)有限制還沒(méi)仔細(xì)看
嘴秸。
2.1 內(nèi)部靜態(tài)類
內(nèi)部靜態(tài)類所有的功能都和外部類相同毁欣,只是為了編排需求放在內(nèi)部。聲明形式如上岳掐,實(shí)例化方式如下:
OuterClass.InnerClass innerInstance = new OuterClass.InnerClass();
內(nèi)部靜態(tài)類只能直接訪問(wèn)外部靜態(tài)類的靜態(tài)變量(所有的類都能凭疮,只要滿足訪問(wèn)控制權(quán)限),但不能訪問(wèn)實(shí)例變量串述。
2.2 內(nèi)部非靜態(tài)類
內(nèi)部非靜態(tài)類是與實(shí)例綁定在一起的执解,只能通過(guò)實(shí)例進(jìn)行實(shí)例化,聲明形式如上纲酗,實(shí)例化方式如下:
OuterClass.InnerClass innerInstance = outerInstance.new InnerClass();
既然是與實(shí)例綁定在一起的衰腌,那么也是可以訪問(wèn)外部類的實(shí)例成員的。
(反射這一部分還沒(méi)有仔細(xì)看)不能對(duì)內(nèi)部非靜態(tài)類進(jìn)行序列化觅赊,因?yàn)椴煌木幾g器對(duì)內(nèi)部非靜態(tài)類的序列化方式不一樣右蕊,所以反序列化的時(shí)候,對(duì)于不同編譯器編譯的非靜態(tài)類可能會(huì)出現(xiàn)問(wèn)題吮螺?
既然內(nèi)部非靜態(tài)類持有對(duì)外部類的引用饶囚,那么內(nèi)部非靜態(tài)類一定不會(huì)在外部類之后被gc了。
3 局域類
局域類為{}
內(nèi)的類鸠补,例如:
public void method(){
class LocalClass{}
}
局域類不可以在外部進(jìn)行實(shí)例萝风,可以在方法內(nèi)部進(jìn)行實(shí)例化。
局域類可以訪問(wèn)局域變量以及實(shí)例變量紫岩,但是如果局域類在靜態(tài)方法中就不可以訪問(wèn)實(shí)例變量闹丐,可以理解為這不是局域類的限制,而是靜態(tài)方法的限制被因。
同時(shí)卿拴,在訪問(wèn)局域變量或者參數(shù)變量的時(shí)候,變量需要是final修飾的梨与,或者方法體當(dāng)中沒(méi)有對(duì)進(jìn)行修改的堕花。這是因?yàn)榫钟蝾愒L問(wèn)局部變量
的時(shí)候是通過(guò)變量捕捉(找了半天,原來(lái)變量捕捉就是復(fù)制一份變量)訪問(wèn)變量粥鞋,所以如果變量本身修改了缘挽,但是沒(méi)有修改局域類中的變量值,就不統(tǒng)一了。這是對(duì)局域變量和參數(shù)變量的限制壕曼,對(duì)實(shí)例變量沒(méi)有這樣的限制苏研。
局域類不可以聲明為靜態(tài)類,這主要是因?yàn)榫钟蝾惪梢栽L問(wèn)實(shí)例變量腮郊,需要持有實(shí)例的引用(未經(jīng)考證)摹蘑。而且局域類中不能定義靜態(tài)成員,除了常量轧飞。大概原因是(沒(méi)有仔細(xì)考究)java運(yùn)行的時(shí)候需要對(duì)靜態(tài)成員進(jìn)行加載衅鹿,但是局域類根據(jù)實(shí)例綁定在一起,所以不對(duì)局域類實(shí)例化过咬,就無(wú)法確定靜態(tài)成員啥的大渤。
4 匿名類
匿名類可以用來(lái)定義接口或者繼承類。匿名類的使用方式為實(shí)例化一個(gè)對(duì)象并賦值給一個(gè)顯示引用或者作為參數(shù):
interface SayHello{}
class AnonClass{}
SayHello sayHello = new SayHello(){}
AnonClass anonClass = new AnonClass(){}
object.method(new interface/class(){})
匿名類對(duì)于外部類的成員訪問(wèn)與局域類相同掸绞。