非静态内部类、静态内部类
首先先说一下非静态内部类与静态内部类
这两者斗是依附于一个外部类的,然后在该外部类里面实现自身的定义,在实现上的区别就是 static
修饰与否的区别:
public class InnerClassTest {
public static void main(String[] args) {
//直接示例化
StaticClass staticClass = new StaticClass();
//先要示例化外部类
InnerClassTest tmp = new InnerClassTest();
//再通过外部类示例外
NonStaticClass nonStaticClass = tmp.new NonStaticClass();
}
public void someMethod(){
}
//非静态内部类
class NonStaticClass {
public void m1() {
someMethod();//InnerClassTest.this.someMethod();
}
}
//静态内部类
static class StaticClass {
public void m1() {
//someMethod(); 无法通过编译
}
}
}
在非静态内部类中,可以直接调用外部类的方法(包括成员方法与静态方法),因为非静态内部类默认持有外部类的引用,调用外部类的方法就是通过该引用实现的,但是静态内部类就不一样了,它无法直接引用外部类的非静态方法,因为它不持有外部类的引用。这个跟类的成员方法与静态方法有点类似。
匿名内部类
然后就是匿名内部类了,实现如下:
new Thread(new Runnable() {
@Override
public void run() {
//TODO
}
}).start();
//或者如下
Runnable runnable = new Runnable() {
@Override
public void run() {
//TODO
}
}
其中初始化 Thread
时传入的参数 new Runnable() {}
就是一个匿名内部类,只能使用一次(这里说的使用一次不是说只能引用或者传递给其他方法一次,而是说每次实例化的时候都需要重新实现所有逻辑),这里所说的 匿名
不是因为没有给实例设置显示的引用变量名,而是说该类在实例的时候没有像下面那样正常的定义(简单的说就是没有定义类名),而是直接实现。
class MyRunnable implements Runnable {
@Override
public void run() {
}
}
new Thread(new MyRunnable()).start();
就像 MyRunnable
就是正常的定义与实现,然后在 Thread
中直接实例化。
当然,需要注意的是,当以匿名内部类直接实现时,该内部类也默认持有外部类的引用,所以,需要注意内存泄露的问题。
匿名内部类与(非)静态内部类的区别
1、匿名内部类没有正常的类名,一般都是直接继承某个类或实现某个接口,而(非)静态内部类有正常的类名、正常的定义与实现
2、匿名内部类每次实例化都要重现实现逻辑,而(非)静态内部类可以直接使用定义的类名实例化
3、匿名内部类与非静态内部类都持有外部类的引用,而静态内部类没有