Java 静态内部类、成员内部类详解
外部类与内部类
众所周知,每个java文件必须有一个与这个java文件同名的外部类,这个外部类可以是public或default的。而除了这个同名外部类,还可以有与这个同名外部类平级的其他外部类,但它们必须是default的。
而内部类是指在外部类的内部再定义一个类。
内部类的分类
我们所说的内部类,官方的叫法是嵌套类(Nested Classes)。嵌套类包括静态内部类(Static Nested Classes)和内部类(Inner Classes)。而内部类分为成员内部类,局部内部类(Local Classes)和匿名内部类(Anonymous Classes)。
而从使用方法来讲,则应该把静态内部类和成员内部类归在一起,因为这两种是可以通过outer.staticInner
或者outer.memberInner
这种.
语法来使用类名的。与之相对,局部内部类和匿名内部类是无法通过.
语法来使用类名,这是因为这二者的使用范围会被限定到某个作用域之内(即在某对{...}
大括号之中),也是因为这二者不是作为外部类的成员(既不是静态成员,也不是实例成员)。
- 非静态内部类,都不能有static成员和static方法。静态属性不依赖于对象,因为它保存在jvm的静态区,所以访问时不需要有存活的对象;而非静态内部类也相当于外部类的非静态属性,而它的表现也符合非静态(需要外部类对象才能创建内部类对象)。而如果一个非静态内部类有了静态属性,而静态属性又不依托于任何内部类实例,这就会破坏非静态内部类的语义。
- 与上一条相对,静态内部类可以拥有,static成员、static方法、静态内部类。
- 静态内部类创建对象时,不需要外部类对象的引用。
- 从静态内部类的对象中,不能访问到外部类对象,即不能访问外部类对象的成员和方法。这是因为没有一个外部类对象的引用。
构造器
class MNA {
private void f() {}
private static void ff(){}
class A {//成员内部类
private void g() {}
public class B {
void h() {
g();
f();
ff();
}
}
}
}
class outer{
void o1(){}
private static void ff(){}
static class staticInner{//静态内部类
void i1(){
//o1();无法通过编译
ff();
}
}
}
public class MultiNestingAccess {
public static void main(String[] args) {
MNA mna = new MNA();
MNA.A mnaa = mna.new A();
MNA.A.B mnaab = mnaa.new B();
mnaab.h();
outer.staticInner sInner = new outer.staticInner();
}
}
- 静态内部类的构造方法正常的一样,只是需要用
.
语法把静态内部类点出来。 - 而成员内部类的构造方法则是,
outerInstance.new inner()
,即外部类对象.new 内部类()
。 - 成员内部类可以随意访问外部类的非静态方法或成员(因为拥有对外部类对象的引用);而静态内部类却不可以。
- 而外部类的静态方法或成员,对于成员内部类和静态内部类来说,都可以访问。因为也不需要对外部类对象的引用。