Java旧版不断发展
我最近偶然發現了JDK API的一個非常有趣的警告,即Class.getConstructors()方法。 它的方法簽名是這樣的:
有趣的是, Class.getConstructor(Class...)返回一個Constructor<T> ,并保持了<T> :
Constructor<T> getConstructor(Class<?>... parameterTypes)為什么會有區別,即為什么第一個方法不返回Constructor<T>[] ?
讓我們考慮一下Javadoc:
請注意,盡管此方法返回一個Constructor <T>對象的數組(也就是此類的構造函數的數組),但此方法的返回類型為Constructor <?> [],而不是Constructor <T> []。預期。 這種信息量較少的返回類型是必需的,因為從此方法返回后,可以修改該數組以容納不同類的Constructor對象,這將違反Constructor <T> []的類型保證。
這是一個艱難的過程。 從歷史上看,這是怎么發生的:
Java 1.0 / Oak:數組
在Java 1.0( Oak編程語言的直接繼承者)中,已經引入了數組。 實際上,它們是在Java 1.2中引入的collections API之前引入的。 數組遭受著我們今天所知道的所有問題,包括它們的協變,這在運行時導致了很多問題,這些問題在編譯時無法檢查:
Object[] objects = new String[1]; objects[0] = Integer.valueOf(1); // OuchJava 1.1:反射API
缺少“不錯的” collection API, Class.getConstructors()方法唯一可能的返回類型是Constructor[] 。 當時的合理決定。 當然,您可能會犯上述相同的錯誤:
Object[] objects = String.class.getConstructors(); objects[0] = Integer.valueOf(1); // Ouch但是除了上述內容之外,您還可以正確地編寫以下代碼:
Constructor[] constructors = String.class.getConstructors(); constructors[0] = Object.class.getConstructor();// MuahahahahahahahaJava 1.2:Collections API
Java從很早的時候就一直向后兼容,甚至從Oak開始。 到目前為止,在這個Stack Overflow問題中,關于Oak的一些向后兼容性已泄漏到Java中,這是一個非常有趣的歷史研究。
雖然使用集合來設計反射API是很自然的,但是現在已經為時已晚。 更好的解決方案可能是:
List getConstructors()但是,請注意,我們還沒有泛型,因此數組實際傳達的類型信息比集合多。
Java 1.5:泛型
在Java 5中,
Constructor[] getConstructors()至
Constructor<?>[] getConstructors()已經出于上述原因進行了處理。 現在,使用集合的替代API肯定會更好:
List<Constructor<T>> getConstructors()但是船開了。
Java,丑陋的疣
Java充滿了這些小警告。 它們都記錄在Javadocs中,并且經常在Stack Overflow中記錄。 就在昨天,我們在Map和ConcurrentHashMap記錄了與全新API相關的新警告 。
“管理權:發人深省”,關于所有這些警告以及Brian Goetz維護這些警告的難易程度的很好演講可以在這里看到:
演講摘要:
語言設計師談論他們正在設計的語言時
翻譯自: https://www.javacodegeeks.com/2015/03/the-java-legacy-is-constantly-growing.html
總結
以上是生活随笔為你收集整理的Java旧版不断发展的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑cpu水冷怎么更换(如何更换水冷)
- 下一篇: 每个人都必须阅读的10篇Java文章