0

0

Java缺失的特性扩展方法是什么

WBOY

WBOY

发布时间:2023-05-20 16:58:43

|

1585人浏览过

|

来源于亿速云

转载

    什么是扩展方法

    扩展方法,就是能够向现有类型直接“添加”方法,而无需创建新的派生类型、重新编译或以其他方式修改现有类型。在调用扩展方法时,与调用实际在类型中定义的方法相比没有明显的区别。

    为什么需要扩展方法

    考虑要实现这样的功能:从 Redis 取出包含多个商品ID的字符串后(每个商品ID使用英文逗号分隔),先对商品ID进行去重(并能够维持元素的顺序),最后再使用英文逗号将各个商品ID进行连接。

    传统写法:

    使用 Stream 写法:

    假设在 Java 中能实现扩展方法,并且我们为数组添加了扩展方法 toList(将数组变为 List),为 List 添加了扩展方法 toSet(将 List 变为 LinkedHashSet),为 Collection 添加了扩展方法 join(将集合中元素的字符串形式使用给定的连接符进行连接),那我们将可以这样写代码:

    相信此刻你已经有了为什么需要扩展方法的答案:

    立即学习Java免费学习笔记(深入)”;

    可以对现有的类库,进行直接增强,而不是使用工具类

    相比使用工具类,使用类型本身的方法写代码更流畅更舒适

    代码更容易阅读,因为是链式调用,而不是用静态方法套娃

    在 Java 中怎么实现扩展方法

    我们先来问问最近大火的 ChatGPT:

    Java缺失的特性扩展方法是什么

    ChatGPT的看法是,在Java中,扩展方法是通过提供的工具类的静态方法实现的。所以接下来我将介绍一种全新的黑科技:

    Manifold

    准备条件

    Manifold 和 Lombok 的工作原理类似,都是通过注解处理器在编译时进行处理。为了有效地使用Manifold,需要在IDEA中安装Manifold IDEA插件

    然后再在项目 pom 的 maven-compiler-plugin 中加入 annotationProcessorPaths:

    如果你的项目中使用了 Lombok,需要把 Lombok 也加入 annotationProcessorPaths:

    编写扩展方法

    JDK 中,String 的 split 方法,使用的是字符串作为参数,即 String[] split(String)。我们现在来为 String 添加一个扩展方法 String[] split(char):按给定的字符进行分割。

    基于 Manifold,编写扩展方法:

    可以发现本质上还是工具类的静态方法,但是有一些要求:

    工具类需要使用 Manifold 的 @Extension 注解

    静态方法中,目标类型的参数,需要使用 @This 注解

    工具类所在的包名,需要以 extensions.目标类型全限定类名 结尾

    —— 用过 C# 的同学应该会会心一笑,这就是模仿的 C# 的扩展方法。

    关于第 3 点,之所以有这个要求,是因为 Manifold 希望能快速找到项目中的扩展方法,避免对项目中所有的类进行注解扫描,提升处理的效率。

    具备了扩展方法的能力,现在我们就可以这样调用了:

    Amazing!而且你可以发现,System.out.println(numStrs.toString()) 打印的居然是数组对象的字符串形式 —— 而不是数组对象的地址。浏览反编译后的 App.class,观察到扩展方法的调用被替换成了静态方法调用

    Java缺失的特性扩展方法是什么

    Haiper
    Haiper

    一个感知模型驱动的AI视频生成和重绘工具,提供文字转视频、图片动画化、视频重绘等功能

    下载

    而数组的 toString 方法,使用的是 Manifold 为数组定义的扩展方法 ManArrayExt.toString(@This Object array):

    Java缺失的特性扩展方法是什么

    [Ljava.lang.String;@511d50c0 什么的,Goodbye,再也不见~

    因为是在编译期将扩展方法的调用替换为静态方法调用,所以使用 Manifold 的扩展方法,即使调用方法的对象是 null 也没有问题,因为处理后的代码是把 null 作为参数传递到对应的静态方法。例如,对于Collection进行扩展:

    然后调用的时候:

    java.lang.NullPointerException,Goodbye,再也不见~

    数组扩展方法

    Java缺失的特性扩展方法是什么

    我们看到 List 这样的写法:@Self 是用来表示被注解的值应该是什么类型,如果是 @Self,即 @Self(false),表示被注解的值和 @This 注解的值是同一个类型;@Self(true) 则表示是数组中元素的类型。

    对于对象数组,我们可以看到 toList 方法返回的就是对应的 List(T 为数组元素的类型):

    Java缺失的特性扩展方法是什么

    但如果是原始类型数组,IDEA 指示的返回值是:

    Java缺失的特性扩展方法是什么

    但是我用的是 Java 啊,擦除法泛型怎么可能拥有 List 这么伟大的功能 —— 所以你只能用原生类型来接收这个返回值 :)

    Java缺失的特性扩展方法是什么

    —— 许个愿,希望 Project Valhalla 早日 GA。

    我们经常在各个项目中看到,大家先把某个对象包装成 Optional,然后进行 filter、map 等。通过 @Self 的类型映射,你可以这样为 Object 加入一个非常实用的办法:

    那么任何对象,都将拥有 asOpt() 方法。

    相比于之前的需要包装一下的不自然:

    你现在可以自然而然的使用 Optional:

    当然,Object 是所有的类的父类,这样做是否合适,还是需要谨慎的思考一下。

    扩展静态方法

    我们都知道 Java9 给集合添加了工厂方法:

    是不是很眼馋?因为如果用的不是 Java9 及以上版本(Java8:直接报我身份证就行),你就得用 Guava 之类的库 —— 然而 ImmutableList.of 用起来终究是比不上 List.of 这样的正统来的自然。

    没关系,Manifold 说:“无所谓,我会出手”。基于 Manifold 扩展静态方法,就是在扩展类的静态方法上,也加上 @Extension:

    然后你就可以欺骗自己已经用上了 Java8 之后的版本 —— 你发任你发,我用 Java8。

    BTW,因为 Object 是所有类的父类,如果你给 Object 添加静态扩展方法,那么意味着你可以在任何地方直接访问到这个静态方法,而不需要 import —— 恭喜你,解锁了 “顶级函数”。

    相关文章

    java速学教程(入门到精通)
    java速学教程(入门到精通)

    java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

    下载

    相关标签:

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

    相关专题

    更多
    php源码安装教程大全
    php源码安装教程大全

    本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

    7

    2025.12.31

    php网站源码教程大全
    php网站源码教程大全

    本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

    4

    2025.12.31

    视频文件格式
    视频文件格式

    本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

    7

    2025.12.31

    不受国内限制的浏览器大全
    不受国内限制的浏览器大全

    想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

    7

    2025.12.31

    出现404解决方法大全
    出现404解决方法大全

    本专题整合了404错误解决方法大全,阅读专题下面的文章了解更多详细内容。

    42

    2025.12.31

    html5怎么播放视频
    html5怎么播放视频

    想让网页流畅播放视频?本合集详解HTML5视频播放核心方法!涵盖<video>标签基础用法、多格式兼容(MP4/WebM/OGV)、自定义播放控件、响应式适配及常见浏览器兼容问题解决方案。无需插件,纯前端实现高清视频嵌入,助你快速打造现代化网页视频体验。

    4

    2025.12.31

    关闭win10系统自动更新教程大全
    关闭win10系统自动更新教程大全

    本专题整合了关闭win10系统自动更新教程大全,阅读专题下面的文章了解更多详细内容。

    3

    2025.12.31

    阻止电脑自动安装软件教程
    阻止电脑自动安装软件教程

    本专题整合了阻止电脑自动安装软件教程,阅读专题下面的文章了解更多详细教程。

    3

    2025.12.31

    html5怎么使用
    html5怎么使用

    想快速上手HTML5开发?本合集为你整理最实用的HTML5使用指南!涵盖HTML5基础语法、主流框架(如Bootstrap、Vue、React)集成方法,以及无需安装、直接在线编辑运行的平台推荐(如CodePen、JSFiddle)。无论你是新手还是进阶开发者,都能轻松掌握HTML5网页制作、响应式布局与交互功能开发,零配置开启高效前端编程之旅!

    2

    2025.12.31

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    Kotlin 教程
    Kotlin 教程

    共23课时 | 2.1万人学习

    C# 教程
    C# 教程

    共94课时 | 5.7万人学习

    Java 教程
    Java 教程

    共578课时 | 39.8万人学习

    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号