内部类是一种代码隐藏机制。
1.普通内部类
内部类不能脱离于外围类而单独存在。
实例化内部类的两种方法——由 外围类的对象.new 内部类名()得到;在外围类的非静态方法中直接new 内部类名。
当某个外围类的对象创建了一个内部类对象时,此内部类会自动得到外围类对象的引用。如何显示地得到呢?可以使用外部类的名字后面紧跟圆点和this。
内部类可以访问外围类的任何方法与字段,包括private。
内部类可以访问外围类的任何方法与字段,包括private。
JDK源码中常见的使用场景就是ArrayList,它实现了Iterable<T>接口,要返回Iterator对象,于是写了一个内部类继承自Iterator<T>。
//: innerclasses/DotThis.java
// Qualifying access to the outer-class object.
public class DotThis {
void f() {
System.out.println("DotThis.f()");
x = 1;
}
private int x;
public class Inner {
public DotThis outer() {
// 当某个外围类的对象创建了一个内部类对象时,此内部类会自动得到外围类对象的引用。
return DotThis.this;
// A plain "this" would be Inner's "this"
}
public void foo() {
//内部类可以访问外围类的任何方法与字段,包括private.
System.out.println(x);
}
}
public static void main(String[] args) {
DotThis dt = new DotThis();
DotThis.Inner dti = dt.new Inner();
dti.outer().f();
dti.foo();
// DotThis.Inner di=new DotThis.Inner(); 这是不允许的,只能由 外围类的对象.new Inner()得到。
}
} /*
* DotThis.f()
* 1
*/
2.静态内部类
静态内部类只能访问外部类的静态成员。生成(new)一个静态内部类不需要外部类成员。
public class DotThis {
static int y=2;
public static class Inner {
public void foo() {
//内部类可以访问外围类的任何方法与字段,包括private.
System.out.println(y);
}
}
public static void main(String[] args) {
DotThis dt = new DotThis();
DotThis.Inner dti = new DotThis.Inner();//不再是 dt.new Inner();
dti = new Inner();//可以省略掉 DotThis.
dti.foo();
}
}
/*
* 2
*/
3.匿名内部类
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
public class A {
public static void main(String[] args) throws InterruptedException {
Timer timer= new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
System.out.println("hi");
}
}, 2000, 500);
TimeUnit.SECONDS.sleep(4);
timer.cancel();
System.out.println(" timer.cancel()");
}
}
/*hi
hi
hi
hi
hi
timer.cancel()*/