JEP 277“增强弃用”非常好。 但这是一个更好的选择
維護API很難。
我們正在維護非常復雜的jOOQ API。 但是就語義版本而言,我們遵循相對寬松的規則 。
當您閱讀Brian Goetz和其他人關于在JDK中保持向后兼容性的評論時,我只能對他們的工作表示敬意。 顯然,我們都希望最終移除Vector , Stack , Hashtable類的東西,但是在collection API周圍存在與向后兼容相關的邊緣情況,普通凡人不會想到。 例如: Java集合為什么不刪除通用方法?
更好的棄用
Stuart Marks又名Dr Deprecator
使用Java 9,Jigsaw和模塊化,這些新功能的主要驅動目標之一是能夠“切斷” JDK的各個部分,并在以后的發行版中輕輕地棄用并刪除它們。 作為此改進的一部分, Stuart Marks AKA Deprecator博士建議了JEP 277:“增強的棄用” 。
這樣做的目的是通過一些附加信息來增強@Deprecated批注,例如:
- 不確定的 。 該API已被棄用,沒有給出任何理由。 這是默認值; 今天隱含棄用的所有內容都有一個不贊成使用的棄用原因。
- 譴責 。 該API已指定在將來的JDK版本中刪除。 請注意,此處使用的“已譴責”一詞在意欲拆除的結構的意義上使用。 該術語并不意味著暗示任何道德譴責。
- 危險的 。 使用此API可能導致數據丟失,死鎖,安全漏洞,錯誤結果或JVM完整性丟失。
- 過時的 。 不再需要此API,應刪除用法。 不存在替代API。 請注意,OBSOLETE API可能會或可能不會標記為CONDEMNED。
- 放棄 。 該API已被較新的API取代,用法應從該API遷移到較新的API。 請注意,SUPERSEDED API可能會或可能不會被標記為CONDEMNED。
- 已取消 。 調用無效或將無條件引發異常。
- 實驗 。 該API并不是規范的穩定部分,它可能會不兼容地更改或隨時消失。
在棄用東西時,能夠傳達棄用的意圖很重要。 也可以通過@deprecated Javadoc標記來實現,該標記可以生成任何類型的文本。
另一種更好的解決方案
上述主張存在以下問題:
- 它是不可擴展的 。 對于JDK庫設計人員來說,以上內容可能就足夠了,但是作為第三方API提供程序的我們將希望枚舉中包含更多元素,而不是CONDEMNED,DANGEROUS等。
- 仍然沒有純文本信息 。 由于我們仍無法正式向注釋提供任何可澄清的文本,例如為什么某事物“危險”的動機,因此該注釋與Javadoc標記之間仍然存在冗余。
- “不推薦使用”是錯誤的 。 將UNIMPLEMENTED或EXPERIMENTAL標記為“已棄用”的想法表明了該JEP的變通方法性質,它試圖在現有名稱中增加一些新功能。
我感到JEP太害怕觸摸太多部分了。 但是,將有一個非常簡單的替代方案,它對每個人都好得多:
public @interface Warning {String name() default "warning";String description() default ""; }無需將可能的警告類型的數量限制為有限的常量列表。 相反,我們可以使用@Warning注釋,該注釋可以包含任何字符串!
當然,JDK可以具有一組眾所周知的字符串值,例如:
public interface ResultSet {@Deprecated@Warning(name="OBSOLETE")InputStream getUnicodeStream(int columnIndex);}要么…
public interface Collection<E> {@Warning(name="OPTIONAL")boolean remove(Object o); }注意,雖然實際上不贊成使用JDBC的ResultSet.getUnicodeStream() ,但我們也可以向Collection.remove()方法添加提示,該方法僅適用于Collection類型,而不適用于其許多子類型。
現在,使用這種方法的有趣之處在于,我們還可以增強有用的@SuppressWarnings批注,因為有時,我們只是知道KnowWhatWeAreDoing?,例如在編寫類似以下內容時:
Collection<Integer> collection = new ArrayList<>();// Compiler!! Stop bitching @SuppressWarnings("OPTIONAL") boolean ok = collection.remove(1);這種方法可以一次性解決許多問題:
- JDK維護人員擁有他們想要的。 輕度棄用JDK的好工具
- 關于 @SuppressWarnings可能發生的事情的記錄不完整的混亂最終將變得更加干凈和正式
- 我們可以根據各種用例向用戶發出大量自定義警告
- 用戶可以在非常細微的級別上使警告靜音
例如: jOOQ的動機是消除DSL equal()方法與不幸的Object.equals()方法之間的歧義:
public interface Field<T> {/*** <code>this = value</code>.*/Condition equal(T value);/*** <strong>Watch out! This is * {@link Object#equals(Object)}, * not a jOOQ DSL feature!</strong>*/@Override@Warning(name = "ACCIDENTAL_EQUALS",description = "Did you mean Field.equal?")boolean equals(Object other); }- 此處描述了該用例的背景: https : //github.com/jOOQ/jOOQ/issues/4763
結論
毫無疑問,JEP 277很有用。 但是它的范圍也非常有限(可能不會進一步延遲Jigsaw嗎?)但是,我希望JDK維護人員可以更徹底地處理生成此類編譯器警告的主題。 這是DoTheRightThing?的絕佳機會
我認為上述“規范”并不完整。 這只是一個粗略的主意。 但是我曾希望作為API設計人員多次嘗試這種機制。 為了向用戶提供有關潛在的API濫用的提示,他們可以通過以下方式將其靜音:
- @SuppressWarnings ,直接在代碼中。
- 易于實現IDE設置。 對于Eclipse,NetBeans和IntelliJ來說,對這些東西實施自定義警告處理將非常簡單。
一旦有了@Warning批注,我們也許可以最后淘汰不那么有用的@Deprecated …
@Warning(name = "OBSOLETE") public @interface Deprecated { }翻譯自: https://www.javacodegeeks.com/2015/12/jep-277-enhanced-deprecation-nice-heres-much-better-alternative.html
總結
以上是生活随笔為你收集整理的JEP 277“增强弃用”非常好。 但这是一个更好的选择的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何环保备案(环保怎么备案)
- 下一篇: linux启动失败修复(linux启动失