2009-11-23 89 views
8

Kushal Paudyal在Java中詢問how deep you can nest inner classes。共識是,雖然語言本身沒有限制,但底層操作系統和文件系統可能會有所限制。嵌套Java內部類超過一個級別是否合理?

你有沒有發現兩層或多層嵌套的內部類有幫助的情況?

更新(11/28):如果你考慮枚舉類,嵌套的第二個層次是有意義的。在最近的一些重構過程中,我簡要地擁有了一個外部類(一個HTTP客戶端),一個內部類(內存中的緩存)以及內部類內部的一個枚舉類(用於緩存驅逐策略)。這似乎沒問題,但對@Thorbjørn來說,我繼續從HTTP客戶端類中提取緩存類和內部枚舉。

回答

4

不,我沒有。

一個類中的一類標準的例子是建造,在那裏你有一個子類,以幫助創造賦予了很多可能的配置方法,適當的實例。

就我個人而言,我會考慮更復雜的嵌套類的情況下需要重構代碼的一個很好的例子。

+0

我傾向於同意。 – 2009-11-23 22:09:54

+0

請注意,我不考慮匿名課程。如果您需要「輕鬆」訪問外部變量,則這是一種必要的痛苦。然而,我強烈認爲另一個匿名類是代碼味道。 – 2009-11-24 09:25:17

3

我還沒有親自遇到多個證明有必要的情況。我可以預見一個可能證明有用的情況。不過,我想象不止兩個。

我想象的例子是Java GUI代碼。在某些情況下,將一個類嵌套在已嵌套的ActionListener中可能會很有用。

1

好的 - 有時候這是有效的。我剛剛做了幾分鐘前。

例如,在一些測試代碼,我寫的,我想建立一些樣板是處理運行多個可調用。創建可調用代碼塊的多個實例所需的樣板文件。在這個例子中,我創建了一個工廠實例以傳遞到threadedTest,並且該工廠創建了新的可調用對象。

@Test public void testXXXXXXXX() throws Throwable { 
    threadedTest(new CallableFactory() { 
     @Override public Callable<Request> create() { 
      return new Callable<Request>() { 
       // might have state 
       @Override public Request call() throws Exception { 
        // do the steps for this test 
        return ...; 
       }}; 
     }}); 
} 

比創建兩個只創建另一個類的新類更簡潔。當然,直到你習慣的樣式這裏的可讀性點球,但...

如果結合這與模板的方法來控制交易或數據庫連接/關閉,這可能最終會深三。 (我有這樣的一些代碼,如果你這樣做,確保你在你的評論寫一個虛擬樣品,並解釋結構井)

+1

這些是匿名的內部類,不是嵌套的內部類。這兩個概念在http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html – 2009-11-23 23:33:31

+0

中的處理方式不同。上面的代碼很容易就是嵌套類,儘管我不想寫它方式;) – 2009-11-30 22:29:40

+1

他們可以,但他們不是。 – 2011-06-04 11:14:13

2

如果你從一些數據生成代碼,嵌套類可以是避免名稱衝突的好方法。

2

我看到使用嵌套類的層數。

有一個名爲串聯(惠普)的傳統機器,原來運行COBOL/C的代碼。有一些後來的「補丁」也啓用了運行java的機器。 COBOL的變量結構自然是多層次的(即使是5個層次也是常見的情況),所以爲了讓Java調用COBOL服務器,java類也被多層次化,以簡化它們之間的數據轉換。

我同意這是一個非常罕見的情況,但無論如何...

2

我知道我在回收舊線程,但它是新的給我:)

我們使用多層次的爲我們的POJO的反序列化JSON(傑克遜)。這裏是JSON,我們可以從一個RESTful Web服務得到一個很小的例子(由):

{ success: true, response: { 
    sales: { item: "123", sales: 3, returns: 1 }, 
    inventory: { item: "567", qty: 100 } 
    } 
} 

我們曾經有過設立類似的POJO:

public class Json1 { 
    private boolean success; 
    private JsonResponse response; 
} 
public class Json1Response { 
    private JsonResponseSales sales; 
    private JsonResponseInventory inventory; 
} 
public class Json1ResponseSales { 
    private String item; 
    private int sales; 
    private int returned; 
} 
public class Json1ResponseInventory { 
    private String item; 
    private int qty; 
} 

我們有很多的這些,併爲我們可能提出的每個Web服務請求提供一個POJO。這種佈局給了我們一些小問題:

  1. 請注意,這一個,相對簡單的例子給了我們四個類文件來跟上。現在再乘以100秒,然後是「難度係數」爲3,以說明大多數JSON比這更混亂。成千上萬的文件。

  2. 字段名稱在整個地方重複使用,並且根據哪個Web服務,相同的字段名稱可能具有不同的內容。 (試想一下,數量可能會回來從一個web服務的字符串,從另一個詮釋,再乘上100秒)。

因爲這些東西捆綁在一起的父/子關係,我們決定一起去這個佈局來代替。

public class Json1 { 
    private boolean success; 
    private JsonResponse response; 

    public class Json1Response { 
    private JsonResponseSales sales; 
    private JsonResponseInventory inventory; 

    public class Json1ResponseSales { 
     private String item; 
     private int sales; 
     private int returned; 
    } 

    public class Json1ResponseInventory { 
     private String item; 
     private int qty; 
    } 
    } 
} 

在這種情況下,我嵌套了兩個深,但它可能更多。也許最多四層。