2010-11-28 4 views
74

это мой код:Возможно ли прочитать значение аннотации в java?

@Column(columnName="firstname") 


private String firstName; 

@Column(columnName="lastname") 
private String lastName; 

public String getFirstName() { 
    return firstName; 
} 

public void setFirstName(String firstName) { 
    this.firstName = firstName; 
} 

public String getLastName() { 
    return lastName; 
} 

public void setLastName(String lastName) { 
    this.lastName = lastName; 
} 

можно ли прочитать значение моей аннотации @Column (ColumnName = «XYZ123») в другом классе?

ответ

19

Я никогда этого не делал, но это выглядит как Reflection. Field - AnnotatedElement, и поэтому он имеет getAnnotation. This page имеет пример (скопирован ниже); довольно просто, если вы знаете класс аннотации, и если в аннотационной политике сохраняется аннотация во время выполнения. Естественно, если политика хранения не сохраняет аннотацию во время выполнения, вы не сможете запросить ее во время выполнения.

Ответ, который был удален (?), Предоставил полезную ссылку на an annotations tutorial, что может оказаться полезным; Я скопировал ссылку здесь, чтобы люди могли ее использовать.

Пример из this page:

import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.reflect.Method; 

@Retention(RetentionPolicy.RUNTIME) 
@interface MyAnno { 
    String str(); 

    int val(); 
} 

class Meta { 
    @MyAnno(str = "Two Parameters", val = 19) 
    public static void myMeth(String str, int i) { 
    Meta ob = new Meta(); 

    try { 
     Class c = ob.getClass(); 

     Method m = c.getMethod("myMeth", String.class, int.class); 

     MyAnno anno = m.getAnnotation(MyAnno.class); 

     System.out.println(anno.str() + " " + anno.val()); 
    } catch (NoSuchMethodException exc) { 
     System.out.println("Method Not Found."); 
    } 
    } 

    public static void main(String args[]) { 
    myMeth("test", 10); 
    } 
} 
85

Да, если аннотация Колонка имеет удержанной среду выполнения

@Retention(RetentionPolicy.RUNTIME) 
@interface Column { 
    .... 
} 

вы можете сделать что-то вроде этого

for (Field f: MyClass.class.getFields()) { 
    Column column = f.getAnnotation(Column.class); 
    if (column != null) 
     System.out.println(column.columnName()); 
} 
+1

я люблю свое решение. Как мы можем сделать это более универсальным, чем вместо MyClass, я хочу использовать T для (Field f: T.class.getFields()) { Столбец столбца = f.getAnnotation (Column.class); if (column! = Null) System.out.println (column.columnName()); } – ATHER 2014-09-15 18:41:20

+0

Ровно! Я тоже пытался понять это. Что делать, если я хочу иметь обработчик аннотации, который не обязательно должен содержать явное имя класса? Можно ли его забрать из контекста; 'это'?? – 5122014009 2014-09-17 06:40:29

+0

Я не уверен, что понимаю, что вам нужно. Пожалуйста, задайте этот вопрос в качестве нового вопроса с полным примером. Вы можете связать его здесь, если хотите. – Cephalopod 2014-09-17 07:46:52

66

Конечно это. Ниже приведен пример аннотации:

@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface TestAnnotation 
{ 
    String testText(); 
} 

И образец аннотированный метод:

class TestClass 
{ 
    @TestAnnotation(testText="zyx") 
    public void doSomething(){} 
} 

И выборочный метод в другом классе, который печатает значение testText:

Method[] methods = TestClass.class.getMethods(); 
for (Method m : methods) 
{ 
     if (m.isAnnotationPresent(TestAnnotation.class)) 
    { 
     TestAnnotation ta = m.getAnnotation(TestAnnotation.class); 
     System.out.println(ta.testText()); 
    } 
} 

Не так много разные для полевых аннотаций, подобных вашим.

Cheerz!

4

Несмотря на то, что все ответы, приведенные до настоящего времени, совершенно верны, следует также иметь в виду google reflections library для более общего и простого подхода к сканированию аннотаций, например.

Reflections reflections = new Reflections("my.project.prefix"); 

Set<Field> ids = reflections.getFieldsAnnotatedWith(javax.persistence.Id.class); 
2

Вы также можете использовать общие типы, в моем случае, принимая во внимание все сказанное, прежде чем вы можете сделать что-то вроде:

public class SomeTypeManager<T> { 

    public SomeTypeManager(T someGeneric) { 

     //That's how you can achieve all previously said, with generic types. 
     Annotation[] an = someGeneric.getClass().getAnnotations(); 

    } 

} 

Помните, что это не будет equival на 100% до SomeClass. class.get (...)();

Но может сделать трюк ...

3

Разрабатывая к ответу @Cephalopod, если вы хотите, чтобы все имена столбцов в списке, вы могли бы использовать этот Oneliner:

List<String> columns = 
     Arrays.asList(MyClass.class.getFields()) 
       .stream() 
       .filter(f -> f.getAnnotation(Column.class)!=null) 
       .map(f -> f.getAnnotation(Column.class).columnName()) 
       .collect(Collectors.toList()); 
1

В общем случае у вас есть частный доступ к полям, так что вы можете» T использовать getFields в отражении. Вместо этого вы должны использовать getDeclaredFields

Итак, во-первых, вы должны знать, если ваша аннотация Колонка имеет задержку выполнения:

@Retention(RetentionPolicy.RUNTIME) 
@interface Column { 
} 

После этого вы можете сделать что-то вроде этого:

for (Field f: MyClass.class.getDeclaredFields()) { 
    Column column = f.getAnnotation(Column.class); 
     // ... 
} 

Очевидно, что вы хотите что-то сделать с полем - установите новое значение, используя значение аннотации:

Column annotation = f.getAnnotation(Column.class); 
if (annotation != null) { 
    new PropertyDescriptor(f.getName(), Column.class).getWriteMethod().invoke(
     object, 
     myCoolProcessing(
      annotation.value() 
     ) 
    ); 
} 

Таким образом, полный код можно посмотреть, как это:

for (Field f : MyClass.class.getDeclaredFields()) { 
    Column annotation = f.getAnnotation(Column.class); 
    if (annotation != null) 
     new PropertyDescriptor(f.getName(), Column.class).getWriteMethod().invoke(
       object, 
       myCoolProcessing(
         annotation.value() 
       ) 
     ); 
} 
Смежные вопросы