嵌套类是指定义在其他类里面的类,其旨在为外围类提供服务。
嵌套类有四种:
1. 静态成员类
2. 非静态成员类
3. 匿名类
4. 局部类
其中非静态成员类、匿名类和局部类又称为内部类。
(一)静态成员类
静态成员类是最简单的嵌套类。静态成员类是外围类的静态成员,且和其他静态成员一样遵守相同的访问规则。注意静态成员类只能访问外围类的静态成员.
静态成员类是最简单的一种嵌套类。最好把它看作是普通的类,只是碰巧被声明在另一个类的内部而已,它可以访问外围类的所有成员,包括那些声明为私有的成员。静态成员类是外围类的一个静态成员,与其他的静态成员一样,也遵守同样的可访问性规则。如果它被声明为私有的,它就只能在外围类的内部才可以被访问,等等。
静态成员类的一种常见用是作为公有的辅助类,仅当与它的外部类一起使用时才有意义。
从语法上讲,静态成员类和非静态成员类之间唯一的区别是,静态成员类的声明中包含了修饰符static。尽管他们的语法非常的相似,但是这两种嵌套类有很大的不同。非静态成员类的每个示例都隐含着与外围类的一个外围实例(enclosing instance)相关联。在非静态成员类的实例方法内部,可以调用外围实例上的方法,或者利用修饰过的this构造获得外围实例的引用。如果嵌套类的实例可以在外围类的实例之外独立存在,这个嵌套类就必须是静态成员类:在没有外围实例的情况下,要想创建非静态成员类的实例是不可能的。
当非静态成员类的实例被创建的时候,它和外围实例之间的关联关系也随之建立起来;而且,这种关联关系以后也不能被修改。通常情况下,当在外围类的某个实例方法的内部调用了非静态成员类的构造器时,这种管理就自动建立起来。使用表达式enclosingInstance.new MemberClass(args)来手工建立这种关系也是有可能的,但是很少使用。正如你预料的那样,这种关联需要消耗非静态成员类的实例空间,并且增加了构造的时间开销。
1.可以访问的方法
外围类:
可以访问任何静态成员类的内容
静态成员类:
不能访问外围类的非静态成员变量
不能访问外围类的非静态成员方法
可以访问外围类的静态成员方法
可以访问外围类的静态成员变量
(二)非静态成员类
与静态成员类不同的是,非静态成员类没有使用static修饰,且每个非静态成员的实例都隐式地对应一个外部类的实例。成员内部类不能含有static的变量和方法,但却可以有static final的变量。非静态成员类可以访问外部类中的任何变量或方法。
1.可以访问的方法
外围类:
使用非静态成员类需要new出来,可以设置private的.
可以调用非静态成员类声明的方法和成员变量
非静态成员类:
不能声明static成员变量
但是可以声明static final成员变量
不能声明static成员方法
(三)匿名类
顾名思义,匿名类就是没有名字的内部类。若满足以下条件,使用匿名类比较合适:
- 只用到类的一个实例
- 类在定以后马上用到
- 类非常小(SUN推荐是在4行以下)
- 给类命名并不会导致你的代码更容易被理解
匿名类不同于Java程序设计语言中的其他任何语法单元。正如你所想象的,匿名类没有名字。它不是外围类的一个成员。它并不与其他的成员一起被声明,而是在使用的同时被声明和实例化。匿名类可以出现在代码中任何允许存在表达式的地方。当且仅当匿名类出现在非静态的环境中时,它才有外围实例。但是即使它们出现在静态的环境中,也不可能拥有任何静态成员。
匿名类的适用性受到诸多的限制。除了在它们被声明的时候之外,是无法将它们实例化的,你不能执行instanceof测试,或者做任何需要命名类的其他事情。你无法声明一个匿名类来实现多个接口,或者扩展一个类,并同时扩展类和实现接口。匿名类的客户端无法调用任何成员,除了从它的超类型中继承得到之外。由于匿名类出现在表达式当中,它们必须保持简短——大约10行或者更少些——否则会影响程序的可读性。
使用匿名类,注意以下几个原则:
- 匿名类不能有构造方法
- 匿名类不能定义任何静态成员、方法和类
- 匿名类不能是public、protected、private和static
- 只能创建匿名类的一个实例
- 一个匿名类一定是在new的后面,用其隐含实现一个接口或实现一个类
- 因匿名类为局部类,所以局部类的所有限制都对其生效
(四)局部类
局部类应该是使用最少的嵌套类。局部类可以和局部变量一样,声明在局部变量所在的任何地方,所以局部类不能有访问说明符。但局部类可以访问当前代码块内的常量和外围类所有的成员。注意:
- 局部类只能在定义该内部类的方法内实例化,不可以在此方法外实例化
- ==局部类对象不能使用该内部类所在方法的非final局部变量==(经实际测试,是可以调用)
局部类是四种嵌套类中用的最少的类。在任何“可以声明局部变量”的地方,都可以声明局部类,并且局部类也遵守同样的作用域规则。局部类与其他三种嵌套类中的每一种都有一些共同的属性。与成员类一样,局部类有名字,可以被重复使用。与匿名类一样,只有当局部类实在非静态环境中定义的时候,才有外围实例,它们也不能包含静态成员。与匿名类一样,它们必须简短以便不会影响到可读性。
(五)总结
以上四种嵌套类,每种都有各自的应用场景。如果内部类需要定义在方法之外或者类内容比较多,则使用内部成员类,至于是静态还是非静态,就看内部类是否需要获取关联的外部类实例,需要则为非静态成员类,否则反之。不过一般能用静态成员类的就最好使用静态成员类,毕竟非静态都牵涉到个隐藏的实例,占用资源。如果可以定义在方法内部,且只需使用一次则使用匿名类,否则使用局部类。
(六)使用内部类优点
1. private修饰的内部类用来隐藏实现的细节2.匿名类使方法实现更简洁、优美(例:工厂方法,适配器方法)3.可用于有效的实现“多重继承”
4.水平有限暂不明。