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

时间:2015-10-14 16:50:05

标签: java java-8 default-method

书中的问题

  

在过去(Java 8之前版本),你被告知向接口添加方法是不好的形式,因为它会破坏现有的代码。现在您被告知可以添加新方法,前提是您还提供默认实现。

     
      
  1. 那有多安全?描述stream接口的新Collection方法导致遗留代码编译失败的情况。
  2.   
  3. 二进制兼容性怎么样?来自JAR文件的遗留代码是否仍会运行?"
  4.   

我的答案如下,但我对它们不太确定。

  1. 只有遗留代码不提供具有相同名称stream且具有相同签名的方法(例如,在实现Collection的遗留类中)时,它才是安全的。否则,这个旧的遗留代码将无法编译。
  2. 我认为保留了二进制兼容性,旧JAR文件中的遗留代码仍将运行。但我对此没有明确的论据。
  3. 任何人都可以确认或拒绝这些答案,或者只是为这些答案添加更多参数,参考或清晰度吗?

1 个答案:

答案 0 :(得分:8)

  1. stream()中的新Collection默认方法返回Stream<E>,也是Java 8中的新类型。如果编译包含{{1},则编译将失败具有相同签名的方法,但返回其他内容,导致返回类型的冲突。

  2. 只要没有重新编译,旧版代码就会继续运行。

  3. 首先,在1.7中,设置以下内容:

    stream()

    使用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

    现在在1.8中,我们将流方法添加到$ javac -target 1.7 -source 1.7 Legacy.java MyCollection.java Main.java $ java Main foo Legacy

    MyCollection

    我们只在1.8中编译public interface MyCollection { public void foo(); public default Stream<String> stream() { return null; } }

    MyCollection

    当然,我们不能再重新编译$ javac MyCollection.java $ java Main foo Legacy

    Legacy.java