简单地说,“内部类”是在另一个类的内部声明的类。从Java 1.1开始,你可在一个类中声明另一个类,这与声明字段和方法非常相似。包装了内部类声明的类就称为“外部类”。
实际上,Java语言规范还允许你做更多的事情,包括:
清单A是类和接口的一些空白声明,它演示了这些可能性。
使用一个import语句,你可像使用其他任何标准类那样省略package名称。此外,在外部类中,可利用简单名称来引用所有内部类和接口(参见清单A中的new语句)。注意从Method1中引用Inner2仍需指定Interface1,因为Inner2在一个不同的级别上。
表A总结了清单A中声明的每个内部类和接口的完全限定名称。用了import语句之后,就可采用较短的形式。当然,在外部类中,你还可省略外部类的名称。
名称 | |
类/接口 | |
Inner1 | mypackage.Inner1 |
Interface1 | mypackage.Interface1 |
Inner2 | mypackage.Interface1.Inner2 |
Interface2 | mypackage.Interface1.Interface2 |
Inner3 | Inner3对于Method1来说是local的,所以它不可在方法外部访问 |
引用内部类
内部类最自然的一种应用就是声明只在另一个类的内部使用的类,或者声明与另一个类密切相关的类。如清单B所示,它是一个链表的简单实现。由于Node类通常只在LinkedList的范围内使用,所以最好将Node声明为LinkedList的一个内部类。
适用于类成员的访问控制修改符也适用于内部类;也就是说,内部类可以具有package、protected、private和public访问权限,它们的语义和正常的语义没有什么不同。由于Node要在LinkedList的外部使用,所以把它声明为public。
然而,修饰符static具有不同的含义。应用于内部类时,它声明的类具有与其他类相同的语义,也就是可进行实例化,并像一个标准类那样使用。惟一的区别就是它拥有对外部类的所有静态成员的完全访问权限。清单C展示了一个简单的程序,它创建一个链表,并将它打印到标准输出设备。