书中的问题:
In the past (pre-Java 8), you were told that it’s bad form to add methods to an interface because it would break existing code. Now you are told that it’s okay to add new methods, provided you also supply a default implementation.
- How safe is that? Describe a scenario where the new
stream
method of theCollection
interface causes legacy code to fail compilation.- What about binary compatibility? Will legacy code from a JAR file still run?"
我的回答如下,但我不太确定。
- 仅当遗留代码不提供具有相同名称
stream
和相同签名的方法时才是安全的(例如,在实现Collection
的遗留类中)。否则,旧的遗留代码将无法编译。 - 我认为二进制兼容性得以保留,旧 JAR 文件中的遗留代码仍将运行。但我对此没有任何明确的论据。
任何人都可以确认或拒绝这些答案,或者只是为这些答案添加更多论据、引用或澄清吗?
最佳答案
新
stream()
Collection
中的默认方法返回Stream<E>
,也是 Java 8 中的一种新类型。如果遗留代码包含stream()
,它将无法编译。具有相同签名的方法,但返回其他内容,导致返回类型冲突。只要不重新编译,遗留代码将继续运行。
首先,在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
关于Java 8 - 默认方法 - 对遗留代码的关注,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33131195/