Java 8 - 默认方法 - 对遗留代码的关注

标签 java java-8 default-method

书中的问题:

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.

  1. How safe is that? Describe a scenario where the new stream method of the Collection interface causes legacy code to fail compilation.
  2. What about binary compatibility? Will legacy code from a JAR file still run?"

我的回答如下,但我不太确定。

  1. 仅当遗留代码不提供具有相同名称 stream 和相同签名的方法时才是安全的(例如,在实现 Collection 的遗留类中)。否则,旧的遗留代码将无法编译。
  2. 我认为二进制兼容性得以保留,旧 JAR 文件中的遗留代码仍将运行。但我对此没有任何明确的论据。

任何人都可以确认或拒绝这些答案,或者只是为这些答案添加更多论据、引用或澄清吗?

最佳答案

  1. stream() Collection 中的默认方法返回 Stream<E> ,也是 Java 8 中的一种新类型。如果遗留代码包含 stream(),它将无法编译。具有相同签名的方法,但返回其他内容,导致返回类型冲突。

  2. 只要不重新编译,遗留代码将继续运行。

首先,在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/

相关文章:

java - 是什么导致此错误 (java) : "Invalid memory access of location 0x0 rip=0x106282bae"

java - 使用 JSON.simple 创建带有键和值的对象和数组

java - 如何在几秒钟内更改和恢复 JTable 中的单元格背景?

java - 使用流和 lambda 在 Java 8 中使用 if-else 条件

java - Spring Boot 中的 JSON Java 8 LocalDateTime 格式

java - 为什么继承的默认方法不能像继承的类方法那样实现另一个接口(interface)?

java - 如何使用 Google Compute Engine Java 客户端创建 SSD 磁盘

java - 如何理解这个 Java 8 Stream collect() 方法?

Java 8 - 两个接口(interface)包含具有相同方法签名但返回类型不同的默认方法,如何覆盖?

java - 为什么 Java 8 中没有默认构造函数?