Collection
の新しいstream()
デフォルトの方法はStream<E>
、それは同じシグネチャを持つstream()
メソッドが含まれている場合、8レガシーコードはコンパイルに失敗しますJavaでも新しいタイプが、その結果、他の何かを返す返します戻り値のタイプの衝突。
レガシーコードは、再コンパイルされない限り、引き続き実行されます。
まず、1.7で、次のように設定
:-source 1.7 -target 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();
}
}
、これはコンパイルし、実行:1.8で今
$ javac -target 1.7 -source 1.7 Legacy.java MyCollection.java Main.java
$ java Main
foo
Legacy
は、我々はMyCollection
にストリーム方式を追加。
public interface MyCollection
{
public void foo();
public default Stream<String> stream() {
return null;
}
}
1.8でMyCollection
のみをコンパイルします。
$ 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
バイナリ互換性を維持しながら行うことが、言語にデフォルトメソッドを追加する主な動機でした。既存のメソッドにデフォルトを追加するのはバイナリとソース互換です。デフォルトで新しいメソッドを追加すると、バイナリとソースとの互換性があります(サブクラスでのクラッシュメソッドとのモジュロ相互作用 - 非最終クラスに新しいメソッドを追加するのと同じ互換性を持っています)。 –
バイナリ互換性は保持されますが、 [このシナリオ](http://stackoverflow.com/q/26816650/2711488)のように、JREライブラリの動作と相互作用するときに問題が発生します。メソッドが* compatible *シグネチャを持つかもしれないと考えるかもしれないので、それを意図せずに新しい 'default'メソッドをオーバーライドし始めます... – Holger