2010-10-17 56 views
0

我想註解一些班級,@MyEntity註釋的Java:集合,它允許使用自定義的註釋對象

public @interface MyEntity {} 

@MyEntity 
public class MyClass { ... } 

並定義只與註解類是允許的集合(無必要它們定義爲public class MyClass implements XXX):

List<MyEntity> list = new ArrayList<MyEntity>(); 
list.add(new MyClass()) 

上面的代碼導致complation錯誤「在ArrayList類型的方法,添加(myEntity所)是不適用的參數(MyClass的)」。有沒有辦法定義一個只允許給定註釋的對象的集合?

+1

您希望在使用註釋時使用接口的*精確*語義嗎?爲什麼? – 2010-10-17 15:58:09

回答

3

簡短的回答是否定的。

你的問題是,List<MyEntity>定義了MyEntity或其子類的列表(即如果我們有@interface AnotherEntity extends MyEntity,那麼我們可以把AnotherEntity放到這個列表中)。

MyClass沒有擴展/實現MyEntity,它用它註釋。

即使有可能,它也不會有效。你不知道哪些方法或字段可用,MyEntity沒有描述你的對象的接口。所以,它唯一可以用來過濾錯誤的插入。您可以輕鬆地實施它提供您的列表實現:

List<?> myEntities = new LinkedList<?> { 
    @Override 
    public boolean add(Object obj) { 
     if (obj != null && obj.getClass().isAnnotationPresent(MyEntity.class)) { 
      return super.add(obj); 
     } 
     throw new IllegalArgumentException("Only objects annotated with MyEntity are allowed"); 
    } 

    @Override 
    public boolean addAll(Collection<?> objs) { 
     //something similar, maybe with Collections2.filter from Google Collections 
    } 
}; 
3

不要以爲這是可能的。爲什麼不讓他們實現一個無方法的接口呢?

1

註釋的存在不會修改註釋的類的類型。

您可以創建一個集合,其中只包含用註釋標註的元素。您需要爲使用反射的集合創建包裝類,以檢查插入時是否存在註釋。

它仍然不會讓你編譯時類型檢查。爲此,您需要直接影響可插入項目類型(接口或超類等)的東西

0

只需重寫list:add,addAll和constructors的方法即可過濾具有預期註釋的類。