2010-11-28 63 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() 
       ) 
     ); 
} 
相關問題