当前位置: 首页 > news >正文

Netty中 ? extends Future<? super V>这种的写法的理解

1. 语法与结构分解

1.1 分解解释

  1. 外层:? extends Future<…>
    • 含义:? 表示某种类型,限制为 Future 或其子类(如 ChannelFuture extends Future)。
    • 作用:使监听器能够处理任何 Future 的子类型,增强灵活性。
    • PECS 原则:外层是“生产者”(Producer),适合只读场景,监听器读取 Future 的状态(如 isSuccess())。
  2. 内层: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 或其子类。

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> {@Overridepublic void channelActive(ChannelHandlerContext ctx) {HttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/");ChannelFuture future = ctx.writeAndFlush(request);future.addListener(new GenericFutureListener<ChannelFuture>() {@Overridepublic void operationComplete(ChannelFuture future) throws Exception {if (future.isSuccess()) {System.out.println("Request sent successfully");} else {System.err.println("Failed: " + future.cause());ctx.close();}}});}@Overrideprotected 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>>() {@Overridepublic 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 误区

  1. 误以为可以修改 Future:
    • 错误:GenericFutureListener 修改 future 的结果。
    • 原因:? extends Future 是只读,监听器不能调用 setSuccess。
  2. 误解内层 ? 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}}
    

http://www.lryc.cn/news/601646.html

相关文章:

  • 使用GPU训练模型
  • MyBatis-Plus高效开发实战
  • 关于GRPC的相关知识。
  • 编程语言Java——核心技术篇(五)IO流:数据洪流中的航道设计
  • 点击劫持:潜藏在指尖的安全陷阱
  • 【Unity3D实例-功能-移动】角色移动-通过WSAD(Transform方式)
  • 《频率之光:共振之恋》
  • 益莱储:明智地投资测试仪器
  • 数据结构的基本知识
  • [STM32][HAL]stm32wbxx 超声波测距模块实现(HY-SRF05)
  • 深度学习在计算机视觉中的应用:对象检测
  • Java面试全栈通关:从微服务到AI的技术深度解析
  • 市电有电检测电路
  • elasticsearch 倒排索引原理详解
  • 湖南(源点咨询)市场调研 如何在行业研究中快速有效介入 起头篇
  • 一场关于电商零售增长破局的深圳探索
  • Python类(class)参数self的理解
  • ROS2总结(二)
  • VMware Workstation Pro虚拟机的下载和安装图文保姆级教程(附下载链接)
  • Mysql 二进制安装常见问题
  • QUARTUS速通流程
  • HCIP---MGRE实验
  • 数学建模——模糊综合评价
  • 2-4、Dify案例实践—基于工作流构建商城用户评价智能分析系统
  • 算法竞赛阶段二-数据结构(37)数据结构循环链表模拟实现
  • print(“\033[31m红\033[32m绿\033[34m蓝\033[0m默认色“)
  • 零基础学习性能测试第五章:JVM性能分析与调优-JVM运行时内存区域介绍
  • Maven之多模块项目管理
  • C语言——关于指针(逐渐清晰版)
  • 嵌入式——单片机的独立按键