Java 8默认方法是否会破坏源兼容性? [英] Do Java 8 default methods break source compatibility?

查看:131
本文介绍了Java 8默认方法是否会破坏源兼容性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常情况下,Java源代码已向前兼容。在Java 8之前,据我所知,编译后的类源都已经与以后的JDK / JVM版本向前兼容。 [更新:这是不正确的,请参阅下面的注释'en en'等。]但是,在Java 8中添加了默认方法后,似乎不再是这种情况。

It has generally been the case the Java source code has been forward compatible. Until Java 8, as far as I know, both compiled classes and source have been forward compatible with later JDK/JVM releases. [Update: this is not correct, see comments re 'enum', etc, below.] However, with the addition of default methods in Java 8 this appears to no longer be the case.

例如,我一直使用的库具有 java.util.List 的实现,其包括 List< V>排序()。此方法返回已排序列表内容的副本。这个库作为jar文件依赖项部署,在使用JDK 1.8构建的项目中运行良好。

For example, a library I have been using has an implementation of java.util.List which includes a List<V> sort(). This method returns a copy of the contents of the list sorted. This library, deployed as a jar file dependency, worked fine in a project being built using JDK 1.8.

但是,后来我有机会使用JDK 1.8重新编译库本身和
我发现库不再编译: List -implementing class有自己的 sort()方法现在与Java 8 java.util.List.sort()默认方法冲突。 Java 8 sort()默认方法对列表进行排序(返回 void );我的库的 sort()方法 - 因为它返回一个新的排序列表 - 具有不兼容的签名。

However, later I had occasion to recompile the library itself using JDK 1.8 and I found the library no longer compiles: the List-implementing class with its own sort() method now conflicts with the Java 8 java.util.List.sort() default method. The Java 8 sort() default method sorts the list in place (returns void); my library's sort() method - since it returns a new sorted list - has an incompatible signature.

所以我的基本问题是:


  • 由于默认方法,JDK 1.8不会引入Java源代码的正向不兼容性吗?

此外:


  • 这是第一次这种前向不兼容的变化吗?

  • 在设计和实施默认方法时是否考虑或讨论过这个问题?是否记录在任何地方?

  • (不可否认的是)不便打折与优惠相比?

以下是一些编译并在1.7下运行的代码示例,
在1.8下运行 - 但不在1.8下编译:

The following is an example of some code that compiles and runs under 1.7 and runs under 1.8 - but does not compile under 1.8:

import java.util.*;

public final class Sort8 {

    public static void main(String[] args) {
        SortableList<String> l = new SortableList<String>(Arrays.asList(args));
        System.out.println("unsorted: "+l);
        SortableList<String> s = l.sort(Collections.reverseOrder());
        System.out.println("sorted  : "+s);
    }

    public static class SortableList<V> extends ArrayList<V> {

        public SortableList() { super(); }
        public SortableList(Collection<? extends V> col) { super(col); }

        public SortableList<V> sort(Comparator<? super V> cmp) {
            SortableList<V> l = new SortableList<V>();
            l.addAll(this);
            Collections.sort(l, cmp);
            return l;
        }

    }

}

以下显示了正在编译(或未能)并正在运行的代码。

The following shows this code being compiled (or failing to) and being run.

> c:\tools\jdk1.7.0_10\bin\javac Sort8.java

> c:\tools\jdk1.7.0_10\bin\java Sort8 this is a test
unsorted: [this, is, a, test]
sorted  : [this, test, is, a]

> c:\tools\jdk1.8.0_05\bin\java Sort8 this is a test
unsorted: [this, is, a, test]
sorted  : [this, test, is, a]

> del Sort8*.class

> c:\tools\jdk1.8.0_05\bin\javac Sort8.java
Sort8.java:46: error: sort(Comparator<? super V>) in SortableList cannot implement sort(Comparator<? super E>) in List
                public SortableList<V> sort(Comparator<? super V> cmp) {
                                       ^
  return type SortableList<V> is not compatible with void
  where V,E are type-variables:
    V extends Object declared in class SortableList
    E extends Object declared in interface List
1 error


推荐答案

JDK 1.8不会引入前向不兼容性对于由于默认方法而导致的Java源代码?

Doesn't JDK 1.8 introduce a forward incompatibility for Java source code due to default methods?

超类或接口中的任何新方法都可能破坏兼容性。默认方法使不太可能接口中的更改将破坏兼容性。从某种意义上说,默认方法打开了向接口添加方法的大门,你可以说默认方法可能会导致一些破坏的兼容性。

Any new method in a superclass or interface can break compatibility. Default methods make it less likely that a change in an interface will break compatibility. In the sense that default methods open the door to adding methods to interfaces, you could say that default methods may contribute to some broken compatibility.

是这是第一个这样的前向不兼容的变化吗?

Is this the first such forward incompatible change?

几乎可以肯定的是,因为自从Java 1.0以来我们一直在从标准库中继承类。

Almost certainly not, since we've been subclassing classes from the standard library since Java 1.0.

在设计和实施默认方法时是否考虑或讨论过这个问题?是否记录在任何地方?

Was this considered or discussed when default methods were designed and implemented? Is it documented anywhere?

是的,它被考虑了。请参阅Brian Goetz 2010年8月的论文通过公共辩护人方法进行界面演变

Yes, it was considered. See Brian Goetz's August 2010 paper "Interface evolution via "public defender" methods":



  1. 来源兼容性

此方案可能会在修改库接口以插入与现有类中的方法不兼容的新方法的范围内引入源不兼容性。 (例如,如果一个类有一个浮点值的xyz()方法并实现了Collection,并且我们将一个int值xyz()方法添加到Collection中,那么现有的类将不再编译。)

It is possible that this scheme could introduce source incompatibilities to the extent that library interfaces are modified to insert new methods that are incompatible with methods in existing classes. (For example, if a class has a float-valued xyz() method and implements Collection, and we add an int-valued xyz() method to Collection, the existing class will no longer compile.)

(不可否认的是)小额优惠与优惠相比是否打折?

Was the (admittedly small) inconvenience discounted versus the benefits?

之前,更改界面肯定会打破兼容性。现在,可能。从'绝对'到'可能'可以看到正面或负面。一方面,它使得向接口添加方法变得可行。另一方面,它打开了你所看到的那种不兼容性的大门,不仅仅是类,还有接口。

Before, changing an interface would definitely break compatibility. Now, it might. Going from 'definitely' to 'might' can be seen either positively or negatively. On the one hand, it makes it feasible to add methods to interfaces. On the other hand, it opens the door to the kind of incompatibility you saw, not just with classes, but with interfaces too.

好处大于不便之处,但是,正如Goetz论文顶部引用的那样:

The benefits are larger than the inconveniences, though, as cited at the top of Goetz's paper:



  1. 问题陈述

一旦发布,就不可能在不破坏现有实现的情况下向接口添加方法。自库发布以来的时间越长,此限制就越有可能导致其维护者感到悲痛。

Once published, it is impossible to add methods to an interface without breaking existing implementations. The longer the time since a library has been published, the more likely it is that this restriction will cause grief for its maintainers.

在Java语言中添加闭包JDK 7给老化的Collection接口带来了额外的压力;闭包最重要的好处之一是它可以开发更强大的库。添加一种语言功能可以实现更好的库,同时不扩展核心库以利用该功能,这将是令人失望的。

The addition of closures to the Java language in JDK 7 place additional stress on the aging Collection interfaces; one of the most significant benefits of closures is that it enables the development of more powerful libraries. It would be disappointing to add a language feature that enables better libraries while at the same time not extending the core libraries to take advantage of that feature.

这篇关于Java 8默认方法是否会破坏源兼容性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆