java的内部类大致是有四种情况。
普通成员内部类
这种形式的内部类的定义就是外部类的一个成员形式。既然作为成员,那么外部类的其他成员方法可以访问使用内部类的class定义进行创建对象。内部类的内部可以使用外部类的成员变量或者成员方法。总之一句话,内部类的定义本身,作为外部类的一个成员来看待。
内部类作为一个成员,他的存在必然要依赖外部类具体的对象实例的。或者说内部类的定义的生存周期是附属于外部类的实例对象的,而不是外部类的class对象。
作为成员可以有可见性修饰符,public、private、protected、和default。这些可见性的规则与一般成员是一致的。
如果要访问一个内部类,假设内部类的可见性是public的。那么需要通过外部类的对象实例,访问内部类的class定义,然后通过class定义来new一个内部类的对象。
如下:
private int i=0;
public OuterClass(int k){
this.i=k;
}
public void add(){
this.i++;
}
public static void main(String[] args){
OuterClass out1 = new OuterClass(1);
OuterClass out2 = new OuterClass(2);
OuterClass.InnerClass in1 = out1.new InnerClass();
out1.add();
OuterClass.InnerClass in3 = out1.new InnerClass();
OuterClass.InnerClass in2 = out2.new InnerClass();
}
public class InnerClass{
public InnerClass(){
System.out.println(i);
}
}
}
输入如下:
1
2
2
由此可见每一个内部类的定义,是与具体的对象实例绑定在一起的。这是从现象上分析得到的结论。具体jvm机制是如何构建内部类和外部类的关系,可能是更加精致的手段。
静态成员内部类
与普通成员内部类的思路比较相近,内部类被定义成静态的成员,那么这个内部类定义就是一个全局性可见的定义了,它不受限于外部类的对象实例,所以它也只能够够访问外部类的静态成员。其他细节就不具体讨论了。
局部内部类
局部的内部类就是指定义在防范内部的类,类的可见性只有在方法内部。也就是只有在方法内部才可以创建内部类的对象。
匿名内部类
匿名内部类就是一种语法糖,本身也是一种局部的内部类。他与局部内部类相比没有类的名称,通过简洁语法的形式直接生成一个类对象。之所以这种操作,是因为匿名内部类的对象只需要一个,没有多个的必要。所以通过语法糖的形式直接创建一个对象即可。如创建事件监听对象,线程对象等。
语句一般为:
Object o = new 抽象类(接口类)([参数]){
方法实现逻辑
}
匿名内部类相当于继承了抽象类或者接口,是他们的一个匿名子类。实例化匿名类对象时会执父类的同参数构造函数。 实际上也可以写成实现一个非抽象类的匿名子类的对象形式。