簡體   English   中英

關於java 8向后兼容性的問題:JDK中的新方法

[英]Issue about java 8 backward compatibility: new methods in JDK

簡單的問題。 在Java 8中,我們在JDK類中有大量新方法。 假設我們使用Java 7(或Java 6)創建了這樣的類:

class MyArrayList<E> extends ArrayList<E> {
        public void sort(Comparator<E> c) {
            // some sort
        }
}

這是非常合理的實施。 現在我們嘗試使用Java 8編譯它並收到可預期的編譯錯誤:

error: name clash: sort(Comparator<E#1>) in MyArrayList and sort(Comparator<? super E#2>) in ArrayList have the same erasure, yet neither overrides the other
            public void sort(Comparator<E> c) {
                        ^   where E#1,E#2 are type-variables:
    E#1 extends Object declared in class I.MyArrayList
    E#2 extends Object declared in class ArrayList

在這里,我想提出2個問題:

  1. 即使使用JDK 8的javac -source 1.7 -target 1.7選項,我也收到同樣的錯誤 - 為什么? 我認為這些選項應該允許編譯遺留代碼。

  2. 一般的向后兼容性怎么樣?

編輯准確地說,可能是我做錯了什么? JDK 1.8.0_65,Mac OS X:

bash-3.2$ javac -version
javac 1.8.0_65
bash-3.2$ javac -source 1.7 -target 1.7 MyArrayList.java 
warning: [options] bootstrap class path not set in conjunction with -source 1.7
MyArrayList.java:7: error: name clash: sort(Comparator<E#1>) in MyArrayList and sort(Comparator<? super E#2>) in ArrayList have the same erasure, yet neither overrides the other
    public void sort(Comparator<E> c) {
                ^
  where E#1,E#2 are type-variables:
    E#1 extends Object declared in class MyArrayList
    E#2 extends Object declared in class ArrayList
1 error
1 warning
  1. -source 1.7僅表示源使用Java 7語言功能。 -target 1.7表示輸出的字節碼針對特定版本的JVM。 但是, 您仍在編譯JDK 8 由於您是交叉編譯的,因此必須使用-bootclasspath-extdirs告訴javac Java 7的引導程序和擴展類存在於-extdirs
  2. 接口中的默認方法 (在Java 8中引入)允許您在不破壞現有代碼的情況下添加新功能。 它不是一個防彈解決方案,可能會有一些小問題( 這個答案會詳細解釋這些問題)。 但總的來說,兼容性問題非常罕見。
  1. 因為即使使用這些選項,您仍然在編譯Java 8類。 JDK不知道在哪個版本的JDK中出現了哪些方法。 所有這些選項都告訴編譯器只接受您正在編譯的代碼中的Java 7語法,並生成Java 7字節碼。 您必須將實際鏈接傳遞給JDK 7類(使用-bootclasspath選項)進行交叉編譯。

  2. 是的,這是一個問題。 並不是很大,並且擁有所有這些新的默認方法的好處比使用一些罕見的非編譯代碼的不便更重要。

暫無
暫無

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

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