Java: коллекция, которая позволяет объектам с пользовательской аннотацией - PullRequest
0 голосов
/ 17 октября 2010

Я хотел бы аннотировать некоторые классы аннотацией @MyEntity

public @interface MyEntity {}

@MyEntity
public class MyClass { ... }

и определить коллекцию, в которой разрешены только классы с этой аннотацией (без необходимости определять их как public class MyClass implements XXX):

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

Приведенный выше код приводит к ошибке компиляции "Метод add (MyEntity) в типе ArrayList не применим для аргументов (MyClass)" .Есть ли способ определить коллекцию, которая позволяет только объекты с данной аннотацией?

Ответы [ 4 ]

3 голосов
/ 17 октября 2010

Короткий ответ - нет.

Ваша проблема в том, что List<MyEntity> определяет список MyEntity или его подклассов (то есть, если у нас есть @interface AnotherEntity extends MyEntity, тогда мы могли бы поместить AnotherEntity в этот список).

Класс MyClass не расширяет / не реализует MyEntity, он аннотирован им.

Даже если бы это было возможно, это было бы неэффективно.Вы не знаете, какие методы или поля доступны, MyEntity не описывает интерфейс вашего объекта.Таким образом, единственное, что может быть использовано для фильтрации неправильных вставок.Вы можете легко реализовать это, предоставив реализацию List:

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 голосов
/ 17 октября 2010

Не думай, что это возможно.Почему бы не сделать так, чтобы они реализовали интерфейс без методов?

1 голос
/ 17 октября 2010

Наличие аннотации не изменяет тип аннотированного класса.

Вы можете создать коллекцию, которая содержит только элементы, аннотированные вашей аннотацией. Вам потребуется создать класс-оболочку для коллекции, которая использует отражение, чтобы проверить наличие аннотации при вставке.

Это все равно не даст вам проверку типов во время компиляции. Для этого вам нужно что-то, что напрямую влияет на тип вставляемых элементов (интерфейс или суперкласс и т. Д.)

0 голосов
/ 17 октября 2010

Просто переопределите методы списка: add, addAll и конструкторы, чтобы отфильтровать классы, которые ожидали аннотацию.

...