嵌套类型的前5个用例
前幾天,在reddit上進(jìn)行了有趣的討論,即靜態(tài)內(nèi)部類。 什么時(shí)候太多?
首先,讓我們回顧一下Java的基本歷史知識(shí)。 Java語(yǔ)言提供了四個(gè)級(jí)別的嵌套類 ,通過(guò)“ Java語(yǔ)言”,我的意思是這些構(gòu)造僅是“語(yǔ)法糖”。 它們?cè)趦H了解普通類的JVM中不存在。
(靜態(tài))嵌套類
在這種情況下, Inner完全獨(dú)立于Outer ,除了公共的共享名稱空間。
內(nèi)部班
class Outer {class Inner {} }在這種情況下, Inner實(shí)例對(duì)其所在的Outer實(shí)例具有隱式引用。 換句話說(shuō),沒有關(guān)聯(lián)的Outer實(shí)例就不會(huì)有Inner實(shí)例。
創(chuàng)建此類實(shí)例的Java方法如下:
Outer.Inner yikes = new Outer().new Inner();看起來(lái)很尷尬的東西很有道理。 考慮在Outer內(nèi)部的某個(gè)地方創(chuàng)建Inner實(shí)例:
class Outer {class Inner {}void somewhereInside() {// We're already in the scope of Outer.// We don't have to qualify Inner explicitly.Inner aaahOK;// This is what we're used to writing.aaahOK = new Inner();// As all other locally scoped methods, we can// access the Inner constructor by // dereferencing it from "this". We just// hardly ever write "this"aaahOK = this.new Inner();} }請(qǐng)注意,就像public或abstract關(guān)鍵字一樣, static關(guān)鍵字對(duì)于嵌套接口是隱式的。 乍看之下,以下假設(shè)語(yǔ)法可能很熟悉……:
class Outer {<non-static> interface Inner {default void doSomething() {Outer.this.doSomething();}}void doSomething() {} }……不可能寫上面的東西。 除了缺少<non-static>關(guān)鍵字外,似乎沒有任何明顯的理由說(shuō)明“內(nèi)部接口”不可行。 我懷疑這是通常的情況–必須有一些與向后兼容和/或多重繼承有關(guān)的邊緣警告。
本地班
class Outer {void somewhereInside() {class Inner {}} }本地類可能是Java中鮮為人知的功能之一,因?yàn)樗鼈儙缀鯖]有用處。 本地類是命名類型,其范圍僅擴(kuò)展到封閉方法。 顯而易見的用例是當(dāng)您想在該方法中多次重用這種類型時(shí),例如在JavaFX應(yīng)用程序中構(gòu)造多個(gè)類似的偵聽器。
匿名班
class Outer {Serializable dummy = new Serializable() {}; }匿名類是只有一個(gè)實(shí)例的另一種類型的子類型。
嵌套類的前5個(gè)用例
如果未在靜態(tài)上下文中定義它們,則所有匿名類,本地類和內(nèi)部類都保留對(duì)其封閉實(shí)例的引用。 如果讓這些類的實(shí)例泄漏到它們的范圍之外,可能會(huì)造成很多麻煩。 在我們的文章中閱讀有關(guān)該麻煩的更多信息: 不要聰明:Double Curly Braces Anti Pattern 。
但是,通常您確實(shí)希望從該封閉實(shí)例中獲利。 具有某種可以在不公開實(shí)際實(shí)現(xiàn)的情況下返回的“消息”對(duì)象可能非常有用:
class Outer {// This implementation is private ...private class Inner implements Message {@Overridepublic void getMessage() {Outer.this.someoneCalledMe();}}// ... but we can return it, being of// type MessageMessage hello() {return new Inner();}void someoneCalledMe() {} }但是,對(duì)于(靜態(tài))嵌套類,沒有封閉范圍,因?yàn)镮nner實(shí)例完全獨(dú)立于任何Outer實(shí)例。 那么,使用這樣的嵌套類而不是頂級(jí)類型有什么意義呢?
1.與外部類型的關(guān)聯(lián)
如果您想與全世界進(jìn)行交流,嘿,這種(內(nèi)部)類型與這種(外部)類型完全相關(guān),并且單獨(dú)使用沒有意義,那么您可以嵌套這些類型。 例如,這是通過(guò)Map和Map.Entry完成的:
public interface Map<K, V> {interface Entry<K, V> {} }2.從外部隱藏外部類型
如果軟件包(默認(rèn))的可見性不足以滿足您的類型的需求,則可以創(chuàng)建private static類,這些private static類僅對(duì)其封裝類型和該封裝類型的所有其他嵌套類型可用。 這實(shí)際上是靜態(tài)嵌套類的主要用例。
class Outer {private static class Inner {} }class Outer2 {Outer.Inner nope; }3.保護(hù)類型
這確實(shí)是一個(gè)非常罕見的用例,但是有時(shí),在類層次結(jié)構(gòu)中,您需要只希望對(duì)給定類型的子類型可用的類型。 這是protected static類的用例:
class Parent {protected static class OnlySubtypesCanSeeMe {}protected OnlySubtypesCanSeeMe someMethod() {return new OnlySubtypesCanSeeMe();} }class Child extends Parent {OnlySubtypesCanSeeMe wow = someMethod(); }4.模擬模塊
與Ceylon不同,Java沒有一流的模塊 。 使用Maven或OSGi,可以向Java的構(gòu)建(Maven)或運(yùn)行時(shí)(OSGi)環(huán)境中添加一些模塊化行為,但是如果要用代碼表示模塊,則實(shí)際上是不可能的。
但是,您可以使用靜態(tài)嵌套類按照約定建立模塊。 讓我們看一下java.util.stream包。 我們可以將其視為一個(gè)模塊,并且在此模塊中,我們有幾個(gè)“子模塊”或類型組,例如內(nèi)部java.util.stream.Nodes類,其大致如下所示:
final class Nodes {private Nodes() {}private static abstract class AbstractConcNode {}static final class ConcNode {static final class OfInt {}static final class OfLong {}}private static final class FixedNodeBuilder {}// ... }所有java.util.stream包都可以使用其中一些Nodes東西,因此我們可以說(shuō),它的編寫方式如下:
- 合成的java.util.stream.nodes子包,僅對(duì)java.util.stream “模塊”可見
- 幾個(gè)java.util.stream.nodes.*類型,也僅對(duì)java.util.stream “模塊”可見
- 合成java.util.stream.nodes包中的幾個(gè)“頂級(jí)”函數(shù)(靜態(tài)方法)
對(duì)我來(lái)說(shuō)看起來(lái)很像錫蘭!
5.外觀原因
最后一點(diǎn)很無(wú)聊。 或者有些人可能會(huì)覺得有趣 。 這是關(guān)于品味或易于寫作的事情。 有些類是如此之小且無(wú)關(guān)緊要,將它們寫在另一個(gè)類中更容易。 為您保存一個(gè).java文件。 為什么不。
結(jié)論
在Java 8時(shí)代,考慮Java的非常古老的功能,該語(yǔ)言可能不會(huì)被證明是非常令人興奮的。 靜態(tài)嵌套類是一些小眾用例的很好理解的工具。
但是,本文的重點(diǎn)是這個(gè)。 每次嵌套類時(shí),如果您絕對(duì)不需要引用封閉的實(shí)例,請(qǐng)確保將其設(shè)為static 。 您永遠(yuǎn)不知道何時(shí)該引用會(huì)在生產(chǎn)中使您的應(yīng)用程序崩潰 。
翻譯自: https://www.javacodegeeks.com/2015/02/top-5-use-cases-for-nested-types.html
總結(jié)
以上是生活随笔為你收集整理的嵌套类型的前5个用例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 我的快乐会回来的是什么歌 你知道了吗
- 下一篇: 养蚕的步骤和注意事项 怎么养蚕