先说个Java 接口的基本常识:
接口( Interface )不能直接实例化,即new一个接口是错误的。只能通过xxx类 implemets XXX接口 来实现接口方法。
最近在阅读代码发现:接口可以被new,这是什么梗?
如果以上代码觉得陌生,先来一段熟悉的味道:
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.print("hello world");
}
};
new Thread(runnable).start();
为什么接口可以这样用呢?先说结论:
- 接口和抽象类不可以被new!
- 这是匿名内部类,只是一种写法上的迷惑而已。
- new 一个接口,可以这样写,运行也不会报错,但运行本质是:编译器帮我们自动生成的一个继承或实现了该接口/抽象类的匿名内部类(所谓匿名只是对开发人员匿名,而非对虚拟机匿名),然后才能在虚拟机上运行,只是编译器帮我们做了这些工作,从原理上并不能说“接口/抽象类可以被new出来
再顺便了解一下匿名内部类的特点:
- 在内部类中使用OuterClassName.this可以访问外围类对象。
- 最大的用途:它可以实现接口或者继承某个类,这样使用内部类时,用基类引用内部类对象,可以屏蔽内部类的细节。这样的好处是,可以实现伪“多重继承”等。
- 普通的内部类不能有static字段和static数据,也不能包含嵌套类。
内部类可以隐藏一些细节,但有些公司的代码规范严禁使用内部类