如果一个类在另外一个类或者接口内被声明,就被称作内嵌类nested class。 同样如果一个接口在另外一个
类或者接口类中被声明,就被称作内嵌接口nested interface。而最高层的类或者最高层的接口类都不能叫做内嵌类。
内嵌类分成四种内嵌类和一种内嵌接口,正式的描述如下:
static member classes and interfaces. 静态类和接口类
non-static member classes 非静态类
local classes 本地类
anonymous classes 匿名类
一个静态类或者接口在类的内部仍旧被定义成一个作为静态的类或者接口。这样的一个内嵌类可以被实例化就
好像一个的最高层类。其中接口类总是被定义不是最高层类或者静态类。
非静态成员类被定义成如果类的实例成员,就类似于类中定义的域和实例方法。
本地类可以被定义在一个上下文块中,如一个方法体内或者一个本地的上下文块中。这有点类似域本地的变量
被定义在方法体中或者本地上下文块中。
匿名类可以被定义成用一种比较随意的方式来进行表达或者实例化。
注意:内嵌类或者接口在他们所在的类中命名不能相同。
class TLC {
static class SMC {} 静态内嵌类
interface SMI {} 静态内嵌接口
class NSMC {} 非静态类(内部类)
void nsm() {
class NSLC {} 本地内部类,在非静态上下文中。
}
static void sm() {
class SLC {} 本地内部类在静态上下文中。
}
SMC nsf = new SMC() {}; 匿名内部类,在非静态上下文中。
static SMI sf = new SMI() {}; 匿名内部类,在静态上下文中。
}
一些基本的原则,
1. 最高层类或者最高层接口必须被定义在Package的层次下,并且这些类的修饰器必须是Public或者是默认的
。而内嵌的静态类或者内嵌的接口则必须被定义在修饰器为静态的类或者接口中。
2. 不管是静态类是不需要通过实例来实例化一个对象的,比如
如果静态内嵌类 StaticTemp
ToplevelClass.StaticTemp NewObject = new ToplevelClass.StaticTemp();
但是换成非静态类 NonStaticTemp的话,我们实例化对象就不能这样了,应该:
ToplevelClass topRef = new ToplevelClass();
ToplevelClass.NonStaticTemp NewObject1 = topRef.new ToplevelClass.NonStaticTemp();
或者如此书写也是正确的
ToplevelClass.NonStaticMemberClass NewObject2 = new ToplevelClass().new NonStaticMemberClass
();
3. 静态的内嵌类可以访问所有的类范围内的静态变量,但不能访问非静态变量。而非静态出了可以访问静态
变量之外,还能访问非静态变量。这点是要特别注意的。
4. 静态内嵌类和非静态内嵌类的另一个区别在于:
A.静态类内中可以定义声明任何的(包括再定义静态的类或者非静态的类)类。
B.非静态类内中只可以定义非静态类,以及修饰器为final的静态变量(field)。(注意修饰为final的类不
能定义。因为这里的原则是static的类只能定义在topLevelClass下或者静态类下。)
5. 本地类是一种比较特殊的内嵌类使用情况。
A.首先本地类定义时,不能在类前放置任何的修饰符,其概念就是本地内嵌类前不能方式
public,protected或者是private修饰字符。
B.本地内嵌类中的实例化过程可以参照2中所描述的内容。
C.本地内嵌类中非静态的内嵌类能访问上下文中的所有变量,以及本地的声明为final的变量。注意非
final的变量是不能被访问的。在静态本地内嵌类可以访问上下文中所有的静态对象,以及定义为final的本地
对象。
D.本地内嵌类中只能访问类中非静态声明的对象以及定义为fianl的静态对象。
6. 匿名类的使用情况。见5,和本地内嵌类的使用方式雷同。