1. 语法与结构分解
1.1 分解解释
- 外层:? extends Future<…>
- 含义:? 表示某种类型,限制为 Future 或其子类(如 ChannelFuture extends Future)。
- 作用:使监听器能够处理任何 Future 的子类型,增强灵活性。
- PECS 原则:外层是“生产者”(Producer),适合只读场景,监听器读取 Future 的状态(如 isSuccess())。
- 内层:Future<? super V>
- 含义:? super V 表示 Future 的结果类型是 V 或其超类(如 V 是 Integer,则结果可以是 Number 或 Object)。
- 作用:允许 Future 接受 V 或其子类的结果,适合写入场景(如 Promise.setSuccess(V))。
- PECS 原则:内层是“消费者”(Consumer),适合写入结果。
1.2 为什么嵌套?
- 灵活性:外层 ? extends Future 允许监听器处理多种 Future 子类(如 ChannelFuture 用于通道操作,DefaultPromise 用于自定义任务)。
- 类型安全:内层 ? super V 确保 Future 的结果类型与监听器的期望兼容,允许写入 V 或其子类。
- 异步模型:Netty 的异步操作(如 ChannelFuture、DefaultPromise)需要处理多种类型的结果,嵌套通配符提供了最大化的兼容性。
2. 理解 ? extends Future<? super V> 的逻辑
2.1 PECS 原则的体现
- PECS(Producer-Extends, Consumer-Super):
- 外层 ? extends Future:监听器是 Future 的“生产者”,读取 Future 的状态(如 isSuccess()、getNow())。
- 内层 ? super V:Future 是结果的“消费者”,可以写入 V 或其子类(如 Promise.setSuccess(V))。
- 逻辑:
- 监听器需要读取 Future 的状态,因此外层使用 ? extends Future 确保兼容所有 Future 子类。
- Future 的结果可能由 Promise 写入,内层使用 ? super V 允许写入 V 或其子类。
2.2 类型关系
- 外层类型:Future<? super V> 或其子类。
- 例如:ChannelFuture(Future)、DefaultPromise。
- 内层类型:V 或其超类。
- 如果 V 是 Integer,则结果类型可以是 Integer、Number 或 Object。
- 组合效果:
- 监听器可以处理 Future、Future 或 ChannelFuture(Future)。
- 结果类型灵活,兼容 V 或其超类。
2.3 为什么需要 ? super V?
- 写入灵活性:Future<? super V> 允许 Promise 写入 V 或其子类。
- 监听器兼容性:监听器可以处理结果类型为 V 的超类的 Future,增加灵活性。
- 示例:
- 如果 V 是 Integer,Promise 可以写入 Integer(Number 是 Integer 的超类)。
- 监听器可以处理 Future,读取结果为 Number。
3. Netty 中的实际案例
3.1 源码分析:GenericFutureListener
-
定义(io.netty.util.concurrent.GenericFutureListener):
//extends Future<?>:类型约束,限制 F 必须是 Future<?> 或其子类。 //Future<?>:Future 接口的泛型形式,? 是一个通配符,表示 Future 的结果类型未知。 public interface GenericFutureListener<F extends Future<?>> { void operationComplete(F future) throws Exception; }
-
使用场景(Future.addListener):
public interface Future<V> { Future<V> addListener(GenericFutureListener<? extends Future<? super V>> listener); }
-
解析:
- 外层 ? extends Future<? super V>:
- ? 表示监听器可以处理 Future<? super V> 或其子类(如 ChannelFuture)。
- 确保监听器兼容多种 Future 类型。
- 内层 ? super V:
- ? super V 表示 Future 的结果类型是 V 或其超类。
- 允许 Promise 写入 V 或其子类。
- 外层 ? extends Future<? super V>:
3.2 示例 1:监听 HTTP 请求写入
-
代码
import io.netty.channel.*; import io.netty.handler.codec.http.*; import io.netty.util.concurrent.GenericFutureListener; public class HttpClientHandler extends SimpleChannelInboundHandler<FullHttpResponse> { @Override public void channelActive(ChannelHandlerContext ctx) { HttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/"); ChannelFuture future = ctx.writeAndFlush(request); future.addListener(new GenericFutureListener<ChannelFuture>() { @Override public void operationComplete(ChannelFuture future) throws Exception { if (future.isSuccess()) { System.out.println("Request sent successfully"); } else { System.err.println("Failed: " + future.cause()); ctx.close(); } } }); } @Override protected void channelRead0(ChannelHandlerContext ctx, FullHttpResponse response) { System.out.println("Response: " + response.status()); ctx.close(); } }
-
分析:
- 类型关系:
- ChannelFuture 是 Future,因此 F 是 ChannelFuture。
- V 是 Void,? super Void 包括 Void 或 Object。
- 外层通配符:? extends Future<? super Void> 允许监听器处理 ChannelFuture。
- 内层通配符:? super Void 表示结果类型可以是 Void(ChannelFuture 无返回值)。
- 只读场景:监听器读取 future.isSuccess() 和 future.cause(),不修改 future。
- 类型关系:
3.3 示例 2:自定义异步任务
-
代码:
import io.netty.util.concurrent.*; public class AsyncTask { public static void main(String[] args) { EventExecutor executor = new DefaultEventExecutor(); DefaultPromise<Number> promise = new DefaultPromise<>(executor); // 写入 Integer(Number 的子类) executor.execute(() -> { try { Thread.sleep(1000); promise.setSuccess(42); // 写入 Number 的子类 } catch (Exception e) { promise.setFailure(e); } }); // 监听结果 promise.addListener(new GenericFutureListener<Future<Number>>() { @Override public void operationComplete(Future<Number> future) throws Exception { if (future.isSuccess()) { System.out.println("Result: " + future.getNow()); } else { System.err.println("Failed: " + future.cause()); } } }); } }
-
分析:
- 类型关系:
- V 是 Number,? super Number 包括 Number 或 Object。
- F 是 Future(DefaultPromise)。
- 外层通配符:? extends Future<? super Number> 允许监听器处理 Future。
- 内层通配符:? super Number 允许 promise.setSuccess(42)(Integer 是 Number 的子类)。
- 写入场景:promise 写入 Integer,监听器读取 Number。
- 类型关系:
4. 常见误区与注意事项
4.1 误区
- 误以为可以修改 Future:
- 错误:GenericFutureListener 修改 future 的结果。
- 原因:? extends Future 是只读,监听器不能调用 setSuccess。
- 误解内层 ? super V:
- 错误:认为 ? super V 限制读取。
- 原因:? super V 允许写入 V 或子类,读取返回 V 或超类。
5. 示例
5.1 示例
-
混合类型监听器:
import io.netty.util.concurrent.*; import java.util.*; public class FutureProcessor { //? extends Future<? super Number> 接受 Future<Number>。 //? super Number 允许写入 Integer。 public static void processFutures(List<? extends Future<? super Number>> futures) { for (Future<? super Number> future : futures) { if (future.isDone() && future.isSuccess()) { System.out.println("Result: " + future.getNow()); } } } public static void main(String[] args) { EventExecutor executor = new DefaultEventExecutor(); List<Future<Number>> futures = new ArrayList<>(); DefaultPromise<Number> promise = new DefaultPromise<>(executor); futures.add(promise); executor.execute(() -> promise.setSuccess(42)); processFutures(futures); // Result: 42 } }