2013-11-22 40 views
0

我想設計一個特殊類型的集合,可能只包含它自己的類型的元素。這個集合類也必須是可擴展的。乍一看,這似乎是一個很簡單的任務:創建一個總是擴展類使用它

public class MyClass<E extends MyClass> implements Collection<E>{ 
    //insert Collection<E> methods here... 
} 

然而,由於這些收藏品之一可能只包含有它的類的實例元素,下面應該是不可能的:

public class MySubclass extends MyClass<MyClass>{} 

我需要的是一個版本的MyClass基本上做以下(不要試圖編譯此):

public class MyClass<E extends this.getClass()> implements Collection<E>{...} 

是否有可能實現這樣的事情?如果是這樣,該怎麼辦?

回答

1

我認爲你正在尋找的簽名會是這樣的:

public class MyClass<E extends MyClass<E>> ... 

的問題,這一點,所以我不認爲你可以強制你從聲明的角度來看需要的是你有一個無限循環。如果集合可能只包含其自己類型的元素,那麼元素只能包含其自身的元素等等。

您現在有一個無限循環,您可能只包含集合,並且在任何時候都沒有集合包含一些THING。

另外,請記住,在運行時,type-erasure會取消所有泛型類型。因此,無論你的常規聲明如何看中的就是在任何時候有人能做到以下幾點,只是得到一個警告:

new MyClass(); 

這是另一個原因,試圖強制執行這種類型的結構可能不會很好地工作。

相反,您可以在提供運行時實施的add方法中進行相應的檢查。儘管如此,仍然有無限循環問題。

EDIT

要執行運行時檢查,執行下列操作:

public boolean add(E element){ 
    if (!(element instanceof MyClass)) 
      throw new IllegalArgumentException("Element is not an instance of MyClass"); 

    // rest of add code here 
} 
+0

的「無限循環」時等於類型的節點的樹是期望的可能是可接受的。而'MyClass();'可以很容易地通過'MyClass''抽象'來禁止。 – Holger

+0

WRT抽象,仍然可以做'SubClass extends MyClass {}'。在Java中不需要使用泛型,它只是給出原始類型警告。 –

+0

+1(如果我可以)簽名;它不允許MySubclass擴展MyClass ,這是朝着正確方向邁出的一步!然而,使MySubclass擴展MyClass仍然允許將一個超類添加到它中(但只限於MyClass,而不是Object)。是的,Holger是正確的,一連串的節點正是這裏所需要的;這些藏品完全是爲了成爲唯一存儲的東西。 也許該運行時強制添加可能對我有用。你會介意如何去做這樣的事情嗎? –

相關問題