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()