title: 内部类的几种用法
date: 2018-2-28 14:18:40
categories:
- JDK
tags:
- JDK
成员内部类
成员内部类是最普通的内部类,它的定义为位于另一个类的内部,
外部类
public class Circle {
double radius = 0;
public Circle(double radius) {
this.radius = radius;
}
public Draw getIntance() {
return new Draw();
}
class Draw { //内部类
public void drawSahpe() {
System.out.println("drawshape");
}
}
public static void main(String[] args) {
// 第一种 构造方法
Circle circle = new Circle(1);
Circle.Draw draw = circle.new Draw();
Circle.Draw draw2 = circle.getIntance();
draw.drawSahpe();
}
}
内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。比如上面的例子,如果成员内部类Inner用private修饰,则只能在外部类的内部访问,如果用public修饰,则任何地方都能访问;如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。这一点和外部类有一点不一样,外部类只能被public和包访问两种权限修饰。
局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。
匿名内部类
匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。匿名内部类在编译的时候由系统自动起名为Outter$1.class。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。
静态内部类
静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法,
public class Outter {
int a = 10;
static int b = 2;
static class Inner{
public Inner() {
System.out.println(a); // 编译错误,不能访问外部类的成原变量
System.out.println(b);
}
}
}
JVM层面
编译器会默认为成员内部类添加了一个指向外部类对象的引用,
至于为什么 JVM要求 局部内部类,匿名内部类只能操作final修饰的变量 。
这是因为, 局部内部类在使用外层变量时会把外部变量复制一份尽自己常量池中,一旦自己修改了这个变量的值,会引发数据不一致的而错误,所以干脆只能final修饰, 不可变吧。