gpt4 book ai didi

java - Java 8 默认方法会破坏源代码兼容性吗?

转载 作者:IT老高 更新时间:2023-10-28 20:27:18 27 4
gpt4 key购买 nike

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

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

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

所以我的基本问题是:

  • JDK 1.8 不是因为默认方法而引入了 Java 源代码的前向不兼容吗?

还有:

  • 这是第一次出现这种向前不兼容的变化吗?
  • 在设计和实现默认方法时是否考虑或讨论了这一点?它是否记录在任何地方?
  • 与好处相比,不便(虽然很小)是否被打折了?

以下是一些在 1.7 下编译运行的代码示例,在 1.8 下运行 - 但在 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;
}

}

}

以下显示此代码正在编译(或失败)并正在运行。

> 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 源代码的前向不兼容吗?

父类(super class)或接口(interface)中的任何新方法都可能破坏兼容性。默认方法不太可能界面中的更改会破坏兼容性。从某种意义上说,默认方法打开了向接口(interface)添加方法的大门,您可以说默认方法可能会导致兼容性受损。

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

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

在设计和实现默认方法时,是否考虑或讨论了这一点?它是否记录在任何地方?

是的,已经考虑过了。请参阅 Brian Goetz 2010 年 8 月的论文 "Interface evolution via “public defender” methods" :

  1. Source compatibility

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.)

与好处相比,(当然很小的)不便是否打折了?

以前,更改界面肯定会破坏兼容性。现在,它可能。从“肯定”到“可能”可以看到正面或负面。一方面,它使得向接口(interface)添加方法成为可能。另一方面,它打开了通向您所看到的那种不兼容的大门,不仅是类,还有接口(interface)。

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

  1. Problem statement

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.

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 - Java 8 默认方法会破坏源代码兼容性吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31188231/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com