Java中Comparator接口匿名内部类创建的构造器相关疑问
为什么接口不能直接实例化,但可以用
new 接口()语法创建匿名内部类? 嘿,这个问题问得特别到位,很多刚接触Java接口的小伙伴都会有这个困惑,我来给你掰扯清楚:
首先明确第一个点:new Comparator(); 这种直接实例化接口的写法确实不合法。因为接口是一种抽象类型,它没有构造方法,也不包含具体的实现逻辑,Java的设计就是不允许直接创建接口的对象——毕竟接口只是定义了一套规范,不是具体的“实体”。
那为什么new Comparator() { ... }是合法的?这其实是个“语法糖”,你并不是在创建Comparator接口的对象,而是在创建一个「实现了Comparator接口的匿名内部类」的对象!
这里的关键是后面跟着的大括号{}:你在这个大括号里重写了接口要求的方法(比如compare),相当于当场定义了一个没有名字的类,这个类实现了Comparator接口,然后紧接着就实例化了这个匿名类的对象。
举个更直观的例子,把匿名写法拆解成等价的具名类写法,你就能一眼看明白:
匿名内部类写法
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class DemoApp { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("apple"); list.add("banana"); list.add("cherry"); // 匿名内部类写法 Collections.sort(list, new Comparator<String>() { @Override public int compare(String o1, String o2) { return o1.length() - o2.length(); } }); } }
等价的具名内部类写法
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; public class DemoApp { // 先定义一个实现了Comparator接口的内部类 static class LengthComparator implements Comparator<String> { @Override public int compare(String o1, String o2) { return o1.length() - o2.length(); } } public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("apple"); list.add("banana"); list.add("cherry"); // 实例化这个具名类,传递给sort方法 Collections.sort(list, new LengthComparator()); } }
这两种写法的效果完全一样,只不过匿名内部类把“定义类”和“实例化对象”合并成了一步,看起来像是在new接口,但本质上new的是那个匿名实现类的对象。
另外,这个匿名类的对象之所以能被赋值给Comparator类型的引用,是因为Java的向上转型特性——就像你可以用父类引用指向子类对象一样,实现了接口的类的对象,也可以被接口类型的引用指向。
内容的提问来源于stack exchange,提问作者elvis
相关产品推荐
相关产品推荐

