当前位置: 首页 > 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.xdnf.cn/news/1196191.html

相关文章:

  • 51c自动驾驶~合集9
  • Java面试宝典:MySQL执行原理二
  • Spring AI 项目实战(二十一):Spring Boot + AI +DeepSeek驱动的智能题库系统(附完整源码)
  • bash的特性-常用的通配符
  • AWS免费套餐全面升级:企业降本增效与技术创新解决方案
  • HCIP---MGRE实验
  • 电子电气架构 --- 软件bug的管理模式
  • logstash采集springboot微服务日志
  • 【奔跑吧!Linux 内核(第二版)】第4章:内核编译和调试
  • 商汤发布具身智能平台,让机器人像人一样和现实世界交互
  • Agent大模型大厂面试题及讲解答案
  • 【分享】外国使馆雷电综合防护系统改造方案(一)
  • 不坑盒子:Word里1秒制作“花括号”题目,多音字组词、形近字组词……
  • 【最新版】防伪溯源一体化管理系统+uniapp前端+搭建教程
  • 【Qt开发】信号与槽(二)-> 信号和槽的使用
  • 积分兑换小程序Java
  • 深入理解 Spring 中的 XmlBeanFactory 原理及实践
  • 数据结构第1问:什么是数据结构?
  • Java 大视界 -- Java 大数据机器学习模型在电商客户细分与精准营销活动策划中的应用(367)
  • 【牛客网C语言刷题合集】(四)
  • PostgreSQL并发控制
  • 机器学习鸢尾花案例
  • KingbaseES聚焦产品上线
  • docker与k8s的容器数据卷
  • 自由学习记录(74)
  • 多租户Kubernetes集群架构设计实践——隔离、安全与弹性扩缩容
  • MYSQL--再谈间隙锁和临键锁
  • RabbitMq 常用命令和REST API
  • 商品中心—1.B端建品和C端缓存
  • Python-初学openCV——图像预处理(四)——滤波器