2015-05-01 3 views
1

Во-первых, я довольно новичок в отражении Java, дженериках и аннотациях.Аннотация класс с пользовательскими аннотациями

Я хотел бы разработать абстрактный класс, который позволил бы мне поддерживать различный набор POJO (value objects, чтобы быть более точным), предоставляя общие реализации/методы на основе пользовательских аннотаций из дочернего класса.

Абстрактный класс

public abstract class AbstractValueObject<T> 

    private Class<T> targetClass; 
    private Integer id; 
    private String rowState; 

    public AbstractValueObject(final Class<T> targetClassToSet) { 

     this.targetClass = targetClassToSet; 

     for (Method method : targetClass.getMethods()) { 

      if (method.isAnnotationPresent(ValueObjectId.class)) { 
       ... invoke getter that has the @ValueObjectId annotation from the child class, and set that value in the id class attribute... 
      } 

      if (method.isAnnotationPresent(ValueObjectRowState.class)) { 
       ... invoke getter that has the @ValueObjectRowState annotation from the child classfro, and set that value in the rowState class attribute... 
      } 
     } 
    } 

    public boolean isNew() { 
    ... logic based on id and rowState ... 
    } 

    public boolean isUpdated() { 
    ... logic based on id and rowState ... 
    } 

    public boolean isDeleted() { 
    ... logic based on id and rowState ... 
    } 

    abstract boolean isValid(); 
} 

класс Пример ребенок

public class MyCustomClass extends AbstractValueObject<MyCustomClass> implements Serializable { 

    private String fileId; 
    private String fileRowState; 

    @ValueObjectId 
    public String getFileId() { 
     return fileId; 
    } 

    public void setFileId(String fileId) { 
     this.fileId = fileId; 
    } 

    @ValueObjectRowState 
    public String getFileRowState() { 
     return fileRowState 
    } 

    public void setFileRowState(String fileRowState) { 
     this.fileRowState= fileRowState; 
    } 

    @Override 
    public boolean isValid() { 
    ...specific implementation... 
    } 
} 

Аннотации

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) 
public @interface ValueObjectId { 
} 

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) 
public @interface ValueObjectRowState { 
} 

Я Насколько это возможно? Я еще не нашел примера, подобного этому требованию.

Спасибо

+0

Почему вы хотите сделать это точно? – durron597

+0

Потому что на самом деле алгоритм для isAdded, isUpdated и isDeleted всегда о тех же двух переменных класса (id и состоянии строки). Один экземпляр MyCustomClass представляет строку в моем представлении. Каждая строка может быть добавлена ​​(то есть она должна быть сохранена), обновлена, то есть должна обновить существующую запись), удалить (удалить объект) или none (существующий, но не измененный). Это просто вопрос повторного использования как можно большего количества кода. –

ответ

1

Почти все должно работать таким образом, однако:

Вы хотите назвать поглотитель на обернутого объекта. Но вы просто передаете класс объекта в качестве параметра. Если ваш подход должен работать, вам придется указать объект как параметр.

Обратите внимание, что отражение не очень эффективно, особенно если оно применяется ко многим объектам. Ваш подход должен будет вычислять его каждый раз, когда новый объект передается конструктору AbstractValueObject, кеширование отражающей информации (Method, MethodHandle) сделает его быстрее.

Если вы знаете все классы объектов, которые удовлетворяют объекту значения (и вы не планируете вводить новые классы во время выполнения), то шаблон посетителя будет более подходящим и более эффективным.

+0

Обязательно найдите шаблон посетителя. Спасибо. –

Смежные вопросы