2010-11-28 64 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提供了这一点。 FieldAnnotatedElement,所以它有getAnnotationThis 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())Column column = f.getAnnotation(Column.class); (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(); 

    } 

} 

请记住,这将不会在100%至SomeClass的equival。 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() 
       ) 
     ); 
} 
相关问题