Java中的內部類雖然在定義上與普通類沒有太多的不同,但由於其位置的特殊性(在另一個類的內部),其訪問方式也比較特殊。本文就內部類Ain作爲外部類Aout成員變量時,從其他類B中訪問AIn的格式進行一些對比和說明。
一、Java中訪問內部類的常見格式
情況1.當內部類Ain爲非靜態時,此時Ain類中的所有成員都爲非靜態,在B中想要訪問Ain類中的成員,必須建立Aout的對象,然後用Aout創建Ain的對象,其具體格式如下:
//Aout.Ain a=new Aout().new Ain();後面再“一點意外的事情”中還會提及第二種格式
情況2.當內部類Ain爲靜態時,此時Ain類中的成員可以爲靜態,也可以爲非靜態,在B中想要訪問Ain類中的成員時,無需建立Aout的對象。然後根據訪問的Ain中的成員是否爲靜態,從而決定是否建立Ain的對象。
1)當訪問Ain中的非靜態成員(如function()),則需建立Ain的對象,其具體格式如下:
//Aout.Ain a=new Aout.Ain();
//a.function();
2)當訪問Ain中的靜態成員(如function()),無需建立Ain的對象,其具體格式如下:
//Aout.Ain.function()
二、一點意外的事情
其中引起我們興趣的是情況2中的2)點,本來的格式應該是
//Aout.Ain a= Aout.new Ain()
但似乎Java語言的創始人,故意將格式改變了,將new放到了前面。這是有道理的,因爲這使得代碼更加美觀,且可讀性更強(因爲new關鍵字的提醒,告訴我們建立一個對象)。於是我們覺得,可能new關鍵字都得提到最前面去。。。。。。
那我們再看看下面這段Demo代碼,就會發現一些意外的事:
//Demo代碼
class Demo
{
class Inner{}
public static void main(String[] args)
{
Demo d=new Demo();
//new d.Inner(); //第一種格式
//d.new Inner(); //第二種格式
}
}
根據我們的猜想,應該是按照第一種格式創建對象。但我們編譯時意外地發現,第一種方式編譯失敗,第二種方式纔是編譯成功的。也就是說無需將new關鍵字提到前面去。
這也是可以理解的。該內部類是非靜態類,所以適用以上所說常見格式中的第一種,只不過這裏分兩步創建內部類對象:先創建外部類對象,再在外部對象的基礎上創建內部類對象。我們若將Demo中註釋去的d用new Demo()帶入,即
//new newDemo().Inner(); //第一種格式
//new Demo().new Inner(); //第二種格式
很容易便發現,第二種格式纔是正確的。。。。
三、對第一種情況的補充
到此,我們需要對“Java中訪問內部類的常見格式”中的第一種情況作出補充,即第一種情況可以有兩種格式:
//一步到位:
//Aout.Ain a=new Aout().new Ain();
//
//或分兩步:
//Aout out =new Aout();
//Aout.Ain a=out.new Ain()