简体   繁体   English

是否可以在不破坏 Java 的情况下向 Comparable 添加默认方法?

[英]Would it be possible to add default methods to Comparable without breaking Java?

I was thinking of proposing a feature request to add default methods called:我正在考虑提出一个添加默认方法的功能请求,称为:

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;
}

to the Comparable interface as it would make the code much more readable - in my opinion.Comparable接口,因为它会使代码更具可读性 - 在我看来。

However, I'm wondering if that would break code.但是,我想知道这是否会破坏代码。 Is there any code such as Lambda's that would break if we add default methods?如果我们添加默认方法,是否有诸如 Lambda 之类的代码会中断?

If I read this correctly I would assume that Lambda's would at least remain working, as long as they won't try to call the new methods, but I'm not sure.如果我阅读正确,我会假设 Lambda 至少会继续工作,只要他们不会尝试调用新方法,但我不确定。 And I don't know if there could be any (obvious) other issues.而且我不知道是否可能存在任何(明显的)其他问题。

Please, no discussion about the possible feature request itself.请不要讨论可能的功能请求本身。

Unfortunately, @BasilBourque's answer is misleading, even though it quotes useful entities.不幸的是,@BasilBourque 的回答具有误导性,即使它引用了有用的实体。

There is no way this feature will be introduced by way of a subinterface.不可能通过子接口引入此功能。 SortedMap/NavigableMap is not applicable: The default mechanism was not around when NavigableMap was introduced! SortedMap/NavigableMap适用:引入NavigableMap时, default机制不存在!

At this point, it may be worthwhile to introduce some or all of the methods in NavigableMap as default methods in SortedMap , with implementations that work on sortedmaps and which will automatically end up getting overridden by any Map impls that implemented NavigableMap already (as they have overridden all of those in their impl).在这一点上,可能值得将NavigableMap中的部分或全部方法作为default方法引入SortedMap ,其实现适用于 sortedmaps 并且最终将自动被任何已经实现 NavigableMap 的 Map 实现覆盖(因为他们已经在他们的 impl 中覆盖了所有这些)。

However, it means that 'Hey, look at NavigableMap which is analogous to SortedMap just like what you want to do to Comparable' is a misleading argument : Your proposal involves adding default methods.但是,这意味着“嘿,看看 NavigableMap,它类似于 SortedMap,就像你想对 Comparable 做的一样”是一个误导性的论点:你的提议涉及添加默认方法。 That just wasn't on the table back then.那只是当时不在桌面上。

In the end what you want is 'almost, but not entirely, backwards compatible'.最后,您想要的是“几乎但不完全向后兼容”。 Oracle/Java Lang Architects tend to say that 'java does not break backwards compatibility' but this is a gross oversimplification and a borderline lie. Oracle/Java Lang 架构师倾向于说“java 不会破坏向后兼容性”,但这是一个严重的过度简化和边缘谎言。 If you ask a little further they will eventually admit that this is not true: The heart of the matter is that java weighs the cost of any backwards break (how likely is it, and what happens to code that did break it? If it silently still compiles and runs but does the wrong thing, that's horrible, if it is a trivial update that a refactor script can automatically apply every time, that's great - and then mix in the odds any given codebase stumbles on it, and you have an idea of 'cost'), vs the benefit of it.如果你问得更远一点,他们最终会承认这不是真的:问题的核心是 java 权衡了任何向后中断的成本(它的可能性有多大,确实破坏它的代码会发生什么?如果它默默地仍然可以编译和运行,但是做错了,这太可怕了,如果重构脚本每次都可以自动应用的微不足道的更新,那就太好了 - 然后混合任何给定代码库偶然发现它的几率,你就有了一个想法'成本'),与它的好处。

The costs are very minor here.这里的成本非常小 It is extremely unlikely any code base would break.任何代码库都极不可能发生故障。 However, if you want to actually propose this feature, it would help a lot to do some research and try to think of any library (or if you can't, look at the top 100 lists which various folks blog about, analysing eg github java projects as source material) to go through a bunch to try to see if the thing that happened with .isEmpty would happen with these methods.但是,如果您想实际提出此功能,那么做一些研究并尝试考虑任何库都会有很大帮助(或者如果您不能,请查看各种人博客的前 100 个列表,例如分析 github java 项目作为源材料)到 go 通过一堆尝试查看使用这些方法是否会发生.isEmpty发生的事情。

Then, there is some bad news: Proposing a java feature is exceedingly unlikely to succeed.然后,有一些坏消息:提出 java 功能极不可能成功。 For some perspective, as author of Project Lombok, someone who's spend many hundreds of hours reading mailing lists like lambda-dev, who has contributed a large part of the actual lambda syntax and conceptual basis, and has held conversations with multiple Java Language Architects at some length (mostly at java conferences), I've sent in a proposal which included a full patch for java itself, and all due updates needed for the JLS, which didn't break backwards compatibility at all, and it never got anywhere.从某种角度来看,作为 Project Lombok 的作者,有人花费数百小时阅读像 lambda-dev 这样的邮件列表,他贡献了大部分实际 lambda 语法和概念基础,并与多个 Java 语言架构师进行了对话一些长度(主要在 java 会议上),我已经发送了一份提案,其中包括 java 本身的完整补丁,以及 JLS 所需的所有适当更新,它根本没有破坏向后兼容性,而且它从来没有得到任何地方。 Not even so much as a JEP.甚至不如 JEP。

Last time I spoke to an Oracle engineer they did promise that things are a little bit better now, but that doesn't go particularly far: I don't know of any java feature around or on the horizon that was sourced by an outsider that got kicked straight to a JEP and got anywhere near the foreseeable horizon of java features in the past 10 years. Last time I spoke to an Oracle engineer they did promise that things are a little bit better now, but that doesn't go particularly far: I don't know of any java feature around or on the horizon that was sourced by an outsider that在过去的 10 年里,他被直接踢到了 JEP 上,并接近了 java 功能的可预见范围。 From time to time someone (usually Joe Darcy or Alex Buckley) runs a project to 'add a bunch of small convenient language changes', such as Project Coin (that was 11 years ago, oof).不时有人(通常是 Joe Darcy 或 Alex Buckley)运行一个项目来“添加一堆方便的小语言更改”,例如Project Coin (那是 11 年前,oof)。 The second take on this is Project Amber , which I think is meant to be a more continuous project vs. coin which had a specific short-lived timespan.对此的第二个看法是Project Amber ,我认为它是一个更连续的项目,而不是具有特定短暂时间跨度的硬币。

The route to get this into java would presumably go through amber.将其放入 java 的路线大概是 go 通过琥珀色。

As commented by Johannes Kuhn , Stuart Marks documented a case where adding the CharSequence.isEmpty() default method to Java 15 broke a third-party library.正如Johannes Kuhn 评论的那样Stuart Marks 记录了一个案例,其中将CharSequence.isEmpty()默认方法添加到 Java 15 破坏了第三方库。

So, given the historic priority to make newer versions of Java maximally backward-compatible with existing apps, the better approach is to define a new interface.因此,考虑到使新版本的 Java 最大限度地向后兼容现有应用程序的历史优先级,更好的方法是定义一个新接口。 The new interface would introduce your new methods.新界面将介绍您的新方法。 In theory the old interface might eventually, after a very long time, be marked deprecated to suggest phasing out the old for the new.理论上,旧接口最终可能会在很长一段时间后被标记为弃用,以建议逐步淘汰旧接口以换取新接口。 In the meantime, existing code would not be disturbed while new code could take advantage of the new ideas.同时,现有代码不会受到干扰,而新代码可以利用新思想。

This was done, for example, in the Map interface.例如,这是在Map接口中完成的。 The sub-interface SortedMap arrived with Java 1.2 (aka Java 2).子接口SortedMap与 Java 1.2(又名 Java 2)一起到达。 Years later, in Java 6, came the idea to extend that interface with additional methods.多年后,在 Java 6 中,出现了使用其他方法扩展该接口的想法。 But revising SortedMap runs the risk of disturbing existing implementations within the bundled Java libraries as well as breaking third-party implementations.但是修改SortedMap存在扰乱捆绑 Java 库中现有实现以及破坏第三方实现的风险。 So they chose to instead define a new interface NavigableMap .所以他们选择定义一个新的接口NavigableMap They made the newer interface NavigableMap a sub-interface of SortedMap .他们使较新的接口NavigableMap成为SortedMap的子接口。

NavigableMap is really just the “2.0” version of SortedMap . NavigableMap实际上只是SortedMap的“2.0”版本。 As far as I know, there is no reason why any implementation would not want to support the larger suite of methods rather than the fewer found in SortedMap .据我所知,任何实现都没有理由不想支持更大的方法套件,而不是在SortedMap中找到的更少的方法。 So, sure, it would be nice to have had only a single such interface rather than two, but c'est la vie .所以,当然,最好只有一个这样的界面而不是两个,但是c'est la vie

Here is a graphic table I made showing the various implementations of the Map interface bundled with Java 11. You can see how the interfaces SortedMap and NavigableMap live side-by-side.这是我制作的图表,显示了与 Java 11 捆绑在一起的Map接口的各种实现。您可以看到SortedMapNavigableMap接口如何并排运行。

Java 11 中的地图实现表,比较它们的特性

I wholeheartedly support your idea of effectively extending Comparable with those particular methods (good naming, too, btw).我全心全意地支持您使用这些特定方法有效扩展Comparable的想法(顺便说一句,命名也很好)。 But I believe your proposal would only fly as a new sub-interface of Comparable .但我相信你的提议只会作为Comparable的新子接口而飞。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在不破坏二进制向后兼容性的情况下,Java 中的扩展方法可能吗? - Extension Methods in Java possible without breaking Binary Backwards Compatibility? 在不破坏实现的情况下向类添加方法 - Add methods to classes without breaking implementations Java:可以将1个非可比较对象添加到TreeSet吗? - Java: Possible to add 1 non-Comparable object to a TreeSet? 是否可以将“method / field”文字与Java / Scala中的类文字进行比较? - Would it be possible to have “method/field” literals comparable to the class literals in Java/Scala? Java Comparable:isLessThan的辅助方法,isGreaterThan,isEqualTo - Java Comparable: helper methods for isLessThan, isGreaterThan, isEqualTo 是否可以在不为 Java 中的每个 pcollection 断行的情况下编写? - Is it possible to write without breaking line for each pcollection in Java? Java:是否可以自动向方法添加日志语句? - Java: Is it possible to automatically add log statements to methods? 需要添加 Comparable 而不修改正在比较的 class - Need to add Comparable without modifying the class that is comparing Java - 可比较 - Java - Comparable Java 和 Comparable - Java and Comparable
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM