
7.6 静态内部类

扫码看视频
当不需要内部类对象与外部类对象有任何联系时,可以使用static关键字来声明这个内部类,这种静态内部类也称为嵌套类(nested class)。当我们创建一个静态内部类的对象时,并不需要先创建外部类的对象,与类中静态成员的约定一样,在静态内部类中也不能访问外部类的非静态成员。
我们看代码7.14。

StaticInnerClass类中定义了一个静态的内部类StaticInner,类中的方法print调用外部类的静态方法output,打印输出静态内部类StaticInner的实例变量index。
在main方法中,可以看到,可以直接创建静态内部类的对象,并不需要依赖外部类对象。与类中静态成员的访问方式一样,静态内部类也是通过“外部类名称.静态内部类名称”来访问的。
实际上,可以把静态内部类看成是包裹在外部类名称空间下的一个独立的类,只不过这个类可以随意访问外部类的所有静态成员。
静态内部类与普通的内部类还有一个重要区别:普通的内部类中的成员不能声明为static,因而也就不能再有嵌套的静态内部类;反之,在静态的内部类中可以声明static成员,自然也就可以有嵌套的静态内部类。
在正常情况下,接口中是不能有任何代码的(Java 8新增的默认方法和静态方法,以及Java 9新增的私有方法除外),不过,在接口中定义一个静态内部类并不违反接口的规则,可以理解为:这个类是接口名称空间下的一个类。代码7.15演示了在接口中的静态内部类。

在接口中定义的类自然就是public和static的,因此不要显式地添加这两个说明符。
由于静态内部类具有这种独立性,所以可以实现一些有意思的功能,比如让接口中的静态内部类实现该接口,相当于接口自带了一个实现,任何需要该接口的地方都可以直接使用接口中静态内部类的实现,非常方便。有不同需求的地方,可以自行实现这个接口。