Java中嵌套类(Nested Classes)定义如下
A nested class is any class whose declaration occurs within the body of another class or interface. A top level class is a class that is not a nested class.
嵌套类是任意声明在另一个类或接口中的类,最外层的类不是嵌套类。按照嵌套类声明位置不同,可以将嵌套类分为三种:成员嵌套类(member nested class)、局部嵌套类(local nested class)、匿名嵌套类(anonymous nested class)。另一方面,通常可将嵌套类分为两种:静态嵌套类和内部类
一、静态嵌套类
静态嵌套类是由static修饰的的成员嵌套类,静态嵌套类内部可以定义静态属性、静态方法。静态嵌套类内部不能访问外部类的非静态变量、非静态方法,同时外部类不能直接访问静态嵌套类的成员变量,可以通过静态嵌套类来访问。静态嵌套类和普通类的访问方式类似,可以使用public、protected、private三种访问控制符。实例化静态内部类不依赖于外部类的实例,直接实例化静态嵌套类即可。静态嵌套类命名格式为:外部类名称+$+静态嵌套类名称。内部静态嵌套类的定义和初始化范例如下:
public class ClassA {
public static class ClassB {
}
public static void main(String [] args) {
ClassA.ClassB classB = new ClassA.ClassB();
System.out.println(classB.getClass().getName());
}
}
输出结果:
com.test.xiaofan.test.ClassA$ClassB
二、内部类
除静态嵌套类外的所有嵌套类被称为内部类,内部类不能被static修饰。内部类分为以下三种:非静态成员类、局部类、匿名类。内部类中不能有静态变量、静态方法、和静态块,内部类可以访问外部类的任何成员变量、成员方法( 包括公有、私有,静态、非静态成员)。
非静态成员类
非静态成员类的实例化依赖于外部类的实例,必须先实例化外部类,再通过外部类实例实例化非静态成员类,非静态成员类的名称与静态嵌套类相同,也可以使用三种访问控制符。非静态成员类定义和实例化范例如下:
public class ClassA {
public class ClassB {
}
public static void main(String [] args) {
ClassB classB = new ClassA().new ClassB();
System.out.println(classB.getClass().getName());
}
}
输出结果:
com.test.xiaofan.test.ClassA$ClassB
局部类
局部嵌套类简称局部类,可以在静态或非静态块、构造器或方法内定义局部类,局部类只在定义的块、构造器或方法内有效,因此局部类不允许使用访问控制符。局部类最多只能有final修饰符,名称形式为:外部类名称+$+序号+内部类名称。局部类定义范例如下:
public class ClassA {
{
final class B {
}
System.out.println(B.class.getName());
}
ClassA() {
class B {
}
System.out.println(B.class.getName());
}
public static void testClassB() {
class B {
}
System.out.println(B.class.getName());
}
public static void main(String [] args) {
ClassA classA = new ClassA();
classA.testClassB();
}
}
输出结果:
com.test.xiaofan.test.ClassA$1B
com.test.xiaofan.test.ClassA$2B
com.test.xiaofan.test.ClassA$3B
匿名类
匿名类是没有名称的类,一般命名形式为:外部类名称+$+匿名类顺序。匿名类没有构造器,只能使用一次。匿名类不能使用关键字和访问控制做修饰符,匿名类和局部类访问规则一致,局部类显示的定义了类,并通过new方式实例化,而匿名类直接new一个类实例,没有定义类。匿名类最常用的方式是回调模式的使用。匿名类根据出现位置不同分为:成员匿名类、局部匿名类和参数匿名类。匿名类使用范例如下:
public abstract class ClassA {
// 成员匿名类
private InterfaceB interfaceB = new InterfaceB() {
{
printName1();
}
public void printName1() {
System.out.println(this.getClass().getName());
}
};
interface InterfaceB {
}
protected abstract void testMethod();
ClassA(InterfaceB interfaceB) {
}
public static void main(String [] args) {
// 局部匿名类
InterfaceB interfaceB = new InterfaceB() {
{
printName2();
}
public void printName2() {
System.out.println(this.getClass().getName());
}
};
// 继承式匿名类,且匿名类可位于参数上
ClassA classA = new ClassA(new InterfaceB() {}) {
@Override
protected void testMethod() {
System.out.println(this.getClass().getName());
}
};
classA.testMethod();
}
}
输出结果:
com.test.xiaofan.test.ClassA$2
com.test.xiaofan.test.ClassA$1
com.test.xiaofan.test.ClassA$4