Java中抽象静态类ChainedReference的new操作符使用疑问
关于Java抽象类通过
new创建实例的疑问解答 核心原理:匿名内部类
你看到的new Sink.ChainedReference<P_OUT, P_OUT>(sink) {...}并不是直接实例化抽象类ChainedReference,而是创建了一个继承自ChainedReference的匿名子类,同时完成这个子类的实例化。
具体细节拆解:
- 你原本的认知没错:抽象类(包括静态抽象嵌套类)本身确实不能用
new直接实例化,因为抽象类包含未实现的抽象方法,不符合可实例化类的要求。 - 此处
new操作的是匿名子类:代码中的大括号{}就是在定义这个匿名子类的内容——你在里面重写begin()、accept()方法,本质是补全抽象类中未实现的抽象方法,让这个匿名子类成为一个可实例化的具体类。 - 父类构造器的作用:
ChainedReference(sink)是调用抽象父类的构造器,用来初始化父类的成员变量(比如示例中的downstream),这是子类实例化时必须执行的初始化步骤。 - 支持添加新变量/方法:你完全可以在这个大括号里定义新的成员变量或方法,就像在普通子类中一样,只不过因为是匿名类,这些新增内容只能在类内部使用,无法在外部直接引用。
对应代码的实际逻辑
回到你给出的opWrapSink方法:
- 方法返回的不是
ChainedReference的实例,而是继承自它的匿名子类实例,这个子类已经实现了begin()和accept()抽象方法,完全符合Sink<P_OUT>接口的要求。 - 这种写法在Java流处理中很常见,目的是快速创建具备特定行为的Sink实现,无需单独定义一个命名子类。
等价的普通子类写法
如果用常规命名子类实现,逻辑完全等价:
// 定义一个命名子类 class MyChainedSink extends Sink.ChainedReference<P_OUT, P_OUT> { public MyChainedSink(Sink<? super P_OUT> downstream) { super(downstream); } @Override public void begin(long size) { // 自定义实现逻辑 } @Override public void accept(P_OUT u) { // 自定义实现逻辑 } } // 实例化并返回 return new MyChainedSink(sink);
匿名内部类只是把子类定义和实例化合并成一步,省去了单独定义命名子类的代码。
内容的提问来源于stack exchange,提问作者Sergey Chernov
相关产品推荐
相关产品推荐

