如何不使用Java 8默认方法
警告:一旦閱讀,您將無法看不到它
我在上一篇博客文章中討論了默認方法的多重繼承,以及它們在編譯和運行時的行為。 這周,我將研究如何使用默認方法進行真正的繼承,實際上,默認方法并不是為這種方法而設計的。 出于這個原因,請您自擔風險閱讀這些行,并不意味著這是要遵循的模式,同樣也并不意味著相反。 我在這里寫的是一些可以使用Java 8編寫的編碼技術,但是它們的可用性至少對我來說值得懷疑。 我也有點害怕從瓶子里放一些香水 ,但另一方面,那些香水根本就不會留在那里。 總有一天有人會說出來。 至少我附上了警告標志。
樣本問題
幾年前,我在一個應用程序上工作,該應用程序使用了許多不同類型的對象,每個對象都有一個名稱。 在許多課程開始包含之后
public String getName(){...} public void setName(String name){...}復制粘貼代碼的方法只是設置者和獲取者,只是讓整個房間難以忍受。 因此我們創建了一個類
class HasName {public String getName(){...}public void setName(String name){...} }每個具有名稱的類都只是擴展了該類。 實際上,它長時間沒有工作。 有些類已經擴展了其他類。 在那種情況下,我們只是試圖在繼承行中將HasName向上移動,但是在某些情況下,它只是行不通。 當我們到達最高峰時,我們意識到那些階級及其后代沒有名字,為什么要強迫他們呢? 老實說,在現實生活中,這比僅僅擁有名字要復雜得多。 如果只是名稱,我們可以將其與其他具有名稱的類一起使用。 事情變得更復雜了,這只會使話題變得更加復雜,并讓我相信:它將變得足夠復雜。
簡介:我們無法實現在某些備用類中實現的某些對象的名稱。 但是現在我們可以使用默認方法做到這一點。
具有默認實現的HasName接口
默認方法僅提供默認功能。 默認方法可以訪問this變量, this變量始終是實現接口的對象,并且代表該方法被調用。 如果有一個接口I和C類實現接口,當一個上的方法C c對象被調用變量this實際上是對象c 。 您將如何實現getName()和setName() ?
這些是訪問對象中的String變量的設置方法和獲取方法。 您不能從界面訪問它。 但是,將值存儲在對象中并不是絕對必要的。 唯一的要求是,為對象設置的任何內容都將相同。 我們可以將值存儲在其他位置,每個對象實例一個。 因此,我們需要一些可以與對象配對的值,并且該值的生存期必須與該對象的生存期相同。 它會響嗎?
這是一個弱哈希表! 是的。 并使用它可以輕松實現HasName接口。
public interface HasName {class Extensions {private static final WeakHashMap<HasName, String> map = new WeakHashMap<>();}default void setName(String name) {Extensions.map.put(this, name);}default String getName() {return Extensions.map.get(this);} }您所要做的就是在該類實現的接口列表的末尾寫: ,HasName ,它神奇地擁有了。
在此示例中,唯一存儲的值是String 。 但是,您可以擁有任何類而不是String并且不僅可以實現setter和getter,而且可以實現對該類執行某些操作的任何方法。 大概這些實現將在類中實現,并且默認方法將僅委托。 您可以將類放置在其他位置,也可以將其作為內部類放在接口中。 品味和風格的問題
結論
接口不能具有實例字段。 為什么? 因為在那種情況下,它們不是接口而是類。 Java沒有多重實現繼承。 也許有,但是“請不要使用”。 默認方法是技術錯誤。 您可以稱其為妥協。 使用功能方法擴展時,需要一些東西來保持JDK庫的向后兼容性。 仍然可以使用弱哈希映射模擬接口中的字段,以訪問要委派的字段和方法的繼承類“ vtable”。 有了它,您可以進行真正的多重繼承。 母親總是警告您的類型。 我告訴你隊友!
另一個警告:以上實現不是線程安全的。 如果嘗試在多線程環境中使用它,則可能會收到ConcurrentModificationException,或者甚至可能會在弱哈希映射上調用get()陷入無限循環,并且永不返回。 我不告訴您在這種情況下如何解決弱哈希映射的使用問題。 或者,好吧,我改變了主意,然后做了:只使用默認方法使用的默認方法。
翻譯自: https://www.javacodegeeks.com/2014/04/how-not-to-use-java-8-default-methods.html
總結
以上是生活随笔為你收集整理的如何不使用Java 8默认方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓代码修改定位(安卓代码修改)
- 下一篇: Java 8星期五:Java 8的阴暗面