问题描述
default boolean greaterThan(T o) {
return compareto(o) > 0;
}
default boolean smallerThan(T o) {
return compareto(o) < 0;
}
default boolean atLeast(T o) {
return compareto(o) >= 0;
}
default boolean atMost(T o) {
return compareto(o) <= 0;
}
到 Comparable
界面,因为它会使代码更具可读性 - 在我看来。
但是,我想知道这是否会破坏代码。如果我们添加默认方法,是否有任何诸如 Lambda 之类的代码会中断?
如果我正确阅读 this,我会假设 Lambda 至少会继续工作,只要它们不会尝试调用新方法,但我不确定。而且我不知道是否有任何(明显的)其他问题。
请不要讨论可能的功能请求本身。
解决方法
不幸的是,@BasilBourque 的回答具有误导性,即使它引用了有用的实体。
无法通过子接口引入此功能。 SortedMap/NavigableMap 不适用:当引入 default
时,NavigableMap
机制还没有出现!
此时,将 NavigableMap
中的部分或全部方法作为 default
中的 SortedMap
方法引入可能是值得的,其实现适用于 sortedmaps 并且会自动结束被任何已经实现 NavigableMap 的 Map impls 覆盖(因为它们已经覆盖了它们的 impl 中的所有那些)。
然而,这意味着“嘿,看看类似于 SortedMap 的 NavigableMap,就像你想对 Comparable 做的一样”是一个误导性的论点:你的提议涉及添加默认方法。那个时候还没有摆在桌面上。
最终您想要的是“几乎但不完全向后兼容”。 Oracle/Java Lang 架构师倾向于说“java 不会破坏向后兼容性”,但这是一种粗略的过度简化和边缘谎言。如果你问得更进一步,他们最终会承认这不是真的:问题的核心是 java 权衡任何向后中断的成本(它的可能性有多大,以及确实破坏它的代码会发生什么?如果它悄悄地仍然可以编译和运行但做错了事情,这太可怕了,如果这是一个重构脚本每次都可以自动应用的微不足道的更新,那就太好了 - 然后混合任何给定的代码库偶然发现它的可能性,你就有了一个想法'成本'),而不是它的好处。
这里的成本非常小。任何代码库都极不可能被破坏。然而,如果你想真正提出这个特性,做一些研究并尝试考虑任何库会很有帮助(或者如果你不能,看看各种人博客上的前 100 个列表,分析例如 github java 项目作为源材料)通过一堆尝试看看 .isEmpty
发生的事情是否会发生在这些方法中。
然后,有一些坏消息:提出一个 Java 特性极不可能成功。从某种角度来看,作为 Project Lombok 的作者,他花了数百个小时阅读 lambda-dev 等邮件列表,他贡献了大部分实际的 lambda 语法和概念基础,并与多个 Java 语言架构师进行了对话一些长度(主要是在 Java 会议上),我提交了一份提案,其中包括 Java 本身的完整补丁,以及 JLS 所需的所有应有更新,这根本没有破坏向后兼容性,而且它从未获得任何进展。甚至不如 JEP。
上次我与 Oracle 工程师交谈时,他们确实承诺现在情况会好一些,但这并没有特别远:我不知道周围或即将出现的任何 Java 功能是由在过去的 10 年里,一个直接被踢到 JEP 并接近可预见的 Java 特性范围的局外人。不时有人(通常是 Joe Darcy 或 Alex Buckley)运行一个项目来“添加一些方便的小语言更改”,例如 Project Coin(那是 11 年前的事了)。对此的第二个看法是 Project Amber,我认为它是一个更连续的项目,而不是具有特定短暂时间跨度的代币。
将其引入 java 的途径大概会经过 amber。
,作为 commented by Johannes Kuhn,Stuart Marks documented a case 将 CharSequence.isEmpty()
默认方法添加到 Java 15 破坏了第三方库。
因此,鉴于历史上优先考虑使用现有应用程序最大限度地 backward-compatible 开发新版本的 Java,更好的方法是定义一个新界面。新界面将介绍您的新方法。理论上,在很长一段时间后,旧界面最终可能会被标记为已弃用,以建议为新界面逐步淘汰旧界面。同时,现有代码不会受到干扰,而新代码可以利用新想法。
例如,这是在 Map
界面中完成的。子接口 SortedMap
随 Java 1.2(又名 Java 2)一起出现。多年后,在 Java 6 中,出现了使用其他方法扩展该接口的想法。但是修改 SortedMap
存在干扰捆绑 Java 库中现有实现以及破坏第三方实现的风险。所以他们选择定义一个新的接口 NavigableMap
。他们将较新的接口 NavigableMap
作为 SortedMap
的子接口。
NavigableMap
实际上只是 SortedMap
的“2.0”版本。据我所知,没有任何实现不希望支持更大的方法套件而不是 SortedMap
中发现的更少的方法。所以,当然,最好只有一个这样的界面而不是两个,但是c'est la vie。
这是我制作的图表,显示了与 Java 11 捆绑在一起的 Map
接口的各种实现。您可以看到接口 SortedMap
和 NavigableMap
如何并排存在.
我全心全意支持您使用这些特定方法有效扩展 Comparable
的想法(顺便说一句,好的命名也是如此)。但我相信你的提议只会作为 Comparable
的新子接口。