在Collection
新stream()
默认方法返回一个Stream<E>
,也是一个新的类型在Java中,如果它包含一个stream()
方法具有相同签名8.遗留代码将无法编译,但没有别的东西返回,导致返回类型的冲突。
遗留代码会继续,只要它不重新编译运行。
首先,在1.7,设置如下:
public interface MyCollection {
public void foo();
}
public class Legacy implements MyCollection {
@Override
public void foo() {
System.out.println("foo");
}
public void stream() {
System.out.println("Legacy");
}
}
public class Main {
public static void main(String args[]) {
Legacy l = new Legacy();
l.foo();
l.stream();
}
}
随着-source 1.7 -target 1.7
,这编译和运行:
$ javac -target 1.7 -source 1.7 Legacy.java MyCollection.java Main.java
$ java Main
foo
Legacy
现在,在1.8中,我们添加了流方法MyCollection
。
public interface MyCollection
{
public void foo();
public default Stream<String> stream() {
return null;
}
}
我们只编译MyCollection
1.8。
$ javac MyCollection.java
$ java Main
foo
Legacy
当然我们不能重新编译Legacy.java
了。
$ javac Legacy.java
Legacy.java:11: error: stream() in Legacy cannot implement stream() in MyCollection
public void stream()
^
return type void is not compatible with Stream<String>
1 error
[相关](http://stackoverflow.com/a/22618640/335858)。 – dasblinkenlight
这样做,同时保持二进制兼容性是添加默认的方法对语言的主要动机。将缺省值添加到现有方法是二进制和源兼容的;添加一个默认的新方法是二进制和源兼容的(与子类中的冲突方法进行模数交换 - 这与向非最终类添加新方法具有相同的兼容性特性。) –
尽管保留了二进制兼容性,但仍可能当它与JRE库行为进行交互时会出现问题,如[本场景](http://stackoverflow.com/q/26816650/2711488)中所述。你也可以考虑一个方法可能有一个* compatible *签名,因此,开始覆盖一个新的'default'方法而不打算它... – Holger