2010-11-28 12 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であるため、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()){ Column column = f.getAnnotation(Column.class); if(列!= null) System.out.println(column.columnName()); } – ATHER

+0

まさに!私もそれを理解するために苦労しています。クラス名を明示的に提供する必要のないアノテーションプロセッサを使用したい場合はどうすればよいですか?文脈からそれを拾うことができますか? 'この'?? – 5122014009

+0

私はあなたの2人が必要としていることを理解していません。それを完全な例で新しい質問として尋ねてください。あなたが望むなら、ここにリンクすることができます。 – Cephalopod

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!

+1

すごく素敵!簡単な例をありがとう。プロセスをステップごとに明確に示しています。 –

+1

注釈の値を取得するプロセスについては、本当に良い説明です。 – Arlind

4

これまでの回答はすべて完全に有効ですが、google reflections libraryには注釈スキャンのためのより一般的で簡単なアプローチがあります。

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(); 

    } 

} 

これは工assに100%equivalないであろうことを、忘れないでください:あなたはまた、アカウントのすべてを考慮して、私の場合には、ジェネリック型を使用することができます

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

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

はあなたのような何かを行うことができます前に、と述べました。 class.get(...)();

しかし、トリックを行うことができます[email protected]の答えにエラボレーション

3

、リスト内のすべてのカラム名を望んでいた場合は、この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()); 
+0

Objects.nonNullを使用してJava 8を完全に取り込みます。 .filter(f - > nonNull(f.getAnnotation(Column.class))) – dehumanizer

1

「あなたはフィールドのプライベートのアクセス権を持っているので、あなたはCAN 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() 
       ) 
     ); 
} 
関連する問題