java8 默认方法_如何不使用Java 8默认方法
java8 默認(rèn)方法
警告:一旦閱讀,您將無法看不到它
我在上一篇博客文章中討論了默認(rèn)方法的多重繼承,以及它們?cè)诰幾g和運(yùn)行時(shí)的行為。 這周,我將研究如何使用默認(rèn)方法進(jìn)行真正的繼承,實(shí)際上,默認(rèn)方法并非為之設(shè)計(jì)的。 出于這個(gè)原因,請(qǐng)您自擔(dān)風(fēng)險(xiǎn)閱讀這些行,并不意味著這是要遵循的模式,同樣也并不意味著相反。 我在這里寫的是一些可以使用Java 8編寫的編碼技術(shù),但其可用性至少對(duì)我來說是個(gè)問題。 我也有點(diǎn)害怕從瓶子里放一些香水 ,但另一方面,那些香水根本就不會(huì)留在那里。 總有一天有人會(huì)說出來。 至少我附上了警告標(biāo)志。
樣本問題
幾年前,我在一個(gè)應(yīng)用程序上工作,該應(yīng)用程序使用了許多不同類型的對(duì)象,每個(gè)對(duì)象都有一個(gè)名稱。 在許多課程開始包含之后
public String getName(){...} public void setName(String name){...}復(fù)制粘貼代碼的方法只不過是設(shè)置方法和獲取方法而已,整個(gè)房間簡(jiǎn)直無法忍受。 因此我們創(chuàng)建了一個(gè)類
class HasName {public String getName(){...}public void setName(String name){...} }每個(gè)具有名稱的類都只是擴(kuò)展了該類。 實(shí)際上,它很長(zhǎng)時(shí)間沒有工作。 有些班級(jí)已經(jīng)擴(kuò)展了其他班級(jí)。 在那種情況下,我們只是試圖在繼承行中將HasName向上移動(dòng),但在某些情況下,它只是行不通。 當(dāng)我們到達(dá)最高峰時(shí),我們意識(shí)到那些階級(jí)及其后代沒有名字,為什么要強(qiáng)迫他們? 老實(shí)說,在現(xiàn)實(shí)生活中,這比僅僅擁有名字要復(fù)雜得多。 如果只是名稱,我們可以將其與其他具有名稱的類一起使用。 事情變得更加復(fù)雜,這只會(huì)使話題變得更加復(fù)雜,并讓我相信:它將變得足夠復(fù)雜。
簡(jiǎn)介:我們無法實(shí)現(xiàn)在某些備用類中實(shí)現(xiàn)的某些對(duì)象的名稱。 但是現(xiàn)在我們可以使用默認(rèn)方法來做到這一點(diǎn)。
具有默認(rèn)實(shí)現(xiàn)的HasName接口
默認(rèn)方法僅提供默認(rèn)功能。 默認(rèn)方法可以訪問this變量, this變量始終是實(shí)現(xiàn)接口的對(duì)象,并且代表該方法被調(diào)用。 如果有一個(gè)接口I和C類實(shí)現(xiàn)接口,當(dāng)一個(gè)上的方法C c對(duì)象被調(diào)用變量this實(shí)際上是對(duì)象c 。 您將如何實(shí)現(xiàn)getName()和setName() ?
這些是訪問對(duì)象中的String變量的設(shè)置方法和獲取方法。 您不能從界面訪問它。 但是,將值存儲(chǔ)在對(duì)象中并不是絕對(duì)必要的。 唯一的要求是,為對(duì)象設(shè)置的任何內(nèi)容都將相同。 我們可以將值存儲(chǔ)在其他位置,每個(gè)對(duì)象實(shí)例一個(gè)。 因此,我們需要一些可以與對(duì)象配對(duì)的值,并且該值的生存期必須與該對(duì)象的生存期相同。 它會(huì)響嗎?
這是一個(gè)弱哈希表! 是的。 并使用它可以輕松實(shí)現(xiàn)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);} }您所要做的就是在該類實(shí)現(xiàn)的接口列表的末尾寫: ,HasName ,它神奇地?fù)碛辛恕?
在此示例中,唯一存儲(chǔ)的值是String 。 但是,您可以擁有任何類而不是String并且不僅可以實(shí)現(xiàn)setter和getter,而且可以實(shí)現(xiàn)對(duì)該類執(zhí)行某些操作的任何方法。 大概這些實(shí)現(xiàn)將在類中實(shí)現(xiàn),并且默認(rèn)方法將僅委托。 您可以將類放置在其他位置,也可以將其作為內(nèi)部類放在接口中。 品味和風(fēng)格的問題
結(jié)論
接口不能具有實(shí)例字段。 為什么? 因?yàn)樵谀欠N情況下,它們不是接口而是類。 Java沒有多重實(shí)現(xiàn)繼承。 也許有,但是“請(qǐng)不要使用”。 默認(rèn)方法是技術(shù)錯(cuò)誤。 您可以稱其為妥協(xié)。 使用功能性方法擴(kuò)展時(shí),需要一些東西來保持JDK庫(kù)的向后兼容性。 您仍然可以使用弱哈希映射模擬接口中的字段,以訪問要委派的字段和方法的繼承類“ vtable”。 有了它,您可以進(jìn)行真正的多重繼承。 您的母親經(jīng)常警告您的類型。 我告訴你隊(duì)友!
另一個(gè)警告:以上實(shí)現(xiàn)不是線程安全的。 如果嘗試在多線程環(huán)境中使用它,則可能會(huì)收到ConcurrentModificationException,或者甚至可能會(huì)在弱哈希映射上調(diào)用get()進(jìn)入無限循環(huán),并且永不返回。 我不告訴您在這種情況下如何解決弱哈希映射的使用問題。 或者,好吧,我改變了主意,然后做了:只使用默認(rèn)方法使用的默認(rèn)方法。
翻譯自: https://www.javacodegeeks.com/2014/04/how-not-to-use-java-8-default-methods.html
java8 默認(rèn)方法
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)總結(jié)
以上是生活随笔為你收集整理的java8 默认方法_如何不使用Java 8默认方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 欧吉桑是什么意思 欧吉桑的含义
- 下一篇: Java:ChronicleMap第3部