我有follwing爪哇9模塊:爲什麼泄漏內部類型的公共API的編譯不會失敗?
module com.example.a {
exports com.example.a;
}
與導出類型:
public class Api {
public static void foo(ImplDetail args) {}
}
和非導出的類型:
package com.example.b.internal;
public class ImplDetail {}
導出的類型使用非導出類型作爲公共方法中的方法參數類型。我假定編譯器會拒絕這種不一致的類配置,因爲其他模塊中的客戶端無法真正調用foo()
方法,因爲它們不能實例化參數類型。
令我驚訝的是,這個模塊由javac編譯成功。我可以看到通過null
的特例,我仍然認爲這樣的API定義格式不正確,認爲它不應該被支持,理想地由編譯器強制執行。
不禁止這種情況的原因是什麼?
感謝您的詳細解答,斯圖爾特!從一個非導出類型派生一個導出的類型似乎同樣不一致,所以我會說單獨應該保證編譯錯誤(對於Sub本身)。但是可能會有幾個編譯步驟中描述的問題。 – Gunnar
@Gunnar在考慮了一段時間之後,我意識到擁有一個作爲私人類的子類的公共類是合理的(如果不常見)。例如,在JDK中,在java.lang中,'StringBuffer'和'StringBuilder'都是'AbstractStringBuilder'的公共子類,它是一個私有類。具有內部私有類的層次結構SB <:ASB <:Object有點奇怪,但它是爲了實現共享而完成的。但請注意,ASB不作爲API中的類型公開。 –
感謝您的跟進。就我個人而言,我覺得這樣的設計很尷尬。一個類型的用戶應該能夠看到IMO類型的完整層次結構。如果是關於實現共享,可以通過委派給一個私有共享類來完成。 – Gunnar