java内部类总结

内部类

  1. 成员内部类
1
2
3
4
5
class Outer{
class inner{
}
}
  • 编译后产生outer.class和outer$inner.class
  1. 方法内部类
1
2
3
4
5
6
7
8
9
class outer{
public void doSomething(){
class inner{
public void seeOuter(){
}
}
}
}
  • 方法内部类只能由该方法实例化
  • 方法内部类对象无法使用方法内非final变量
  • 因为方法的局部变量位于栈上,只存在于该方法的生命期内。当一个方法结束,其栈结构被删除,局部变量成为历史。但是该方法结束之后,在方法内创建的内部类对象可能仍然存在于堆中!例如,如果对它的引用被传递到其他某些代码,并存储在一个成员变量内。正因为不能保证局部变量的存活期和方法内部类对象的一样长,所以内部类对象不能使用它们。
  1. 静态嵌套类
1
2
3
4
5
6
7
8
9
10
11
class outer{
static class inner{
}
class test{
public static void main(String[] args){
Outer.inner obj = Outer.new inner();
}
}
}
  • 可类比静态域
  • 静态内部类中可以定义静态或者非静态的成员。
    从技术上讲,静态嵌套类不属于内部类。因为内部类与外部类共享一种特殊关系,更确切地说是对实例的共享关系。而静态嵌套类则没有上述关系。它只是位置在另一个类的内部,因此也被称为顶级嵌套类。
    静态的含义是该内部类可以像其他静态成员一样,没有外部类对象时,也能够访问它。静态嵌套类仅能访问外部类的静态成员和方法。
  • 在静态方法中定义的内部类也是StaticNested Class,这时候不能在类前面加static关键字,静态方法中的StaticNested Class与普通方法中的内部类的应用方式很相似,它除了可以直接访问外部类中的static的成员变量,还可以访问静态方法中的局部变量,但是,该局部变量前必须加final修饰符。
  1. 匿名内部类
1
2
3
new ParentName(){
//内部类的定义
}
  • 使用情景
  1. 只用到类的一个实例
  2. 类在定义后马上用到
  3. 类非常小
  4. 不会对可读性影响太大
  • 注意
  1. 不能有构造方法

  2. 不能定义任何静态成员、静态方法

    理由:匿名内部类是晚于外部类加载的,但是匿名内部类和其对象几乎是同时加载的,但是还是早于对象加载,而静态内容是属于类的,当类加载的时候就开始加载,所以当匿名内部类中有静态内容,就会随着类加载,而这时和对象创建冲突。

  3. 不能是public protected private static

  4. 只能创建一个实例

  5. 跟在new后面,隐含实现一个接口或一个类

为何要使用内部类

  • 典型的情况是,内部类继承自某个类或实现某个接口,内部类的代码操作创建其他外围类的对象。所以你可以认为内部类提供了某种进入其外围类的窗口。使用内部类最吸引人的原因是:

  • 每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”。