簡體   English   中英

Java 8 - 默認方法 - 對遺留代碼的關注

[英]Java 8 - default methods - concerns for legacy code

一本書的問題

在過去(Java 8之前版本),您被告知將方法添加到接口是一種糟糕的形式,因為它會破壞現有代碼。 現在您被告知可以添加新方法,前提是您還提供默認實現。

  1. 這有多安全? 描述一個場景,其中Collection接口的新stream方法導致遺留代碼編譯失敗。
  2. 二進制兼容性怎么樣? 來自JAR文件的遺留代碼是否仍會運行?“

我的答案如下,但我不太確定。

  1. 僅當遺留代碼不提供具有相同名稱stream和相同簽名的方法時(例如,在實現Collection的遺留類中),它才是安全的。 否則,這個舊的遺留代碼將無法編譯。
  2. 我認為保留了二進制兼容性,舊JAR文件中的遺留代碼仍將運行。 但我對此沒有明確的論據。

任何人都可以確認或拒絕這些答案,或者只是為這些答案添加更多參數,參考或清晰度嗎?

  1. Collection的新stream()默認方法返回一個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;
    }
}

我們只在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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM