Is it possible to read the value of a annotation i

2019-01-03 05:25发布

this is my code:

@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;
 }

is it possible to read the value of my annotation @Column(columnName="xyz123") in another class?

7条回答
不美不萌又怎样
2楼-- · 2019-01-03 05:51

In common case you have private access for fields, so you CAN'T use getFields in reflection. Instead of this you should use getDeclaredFields

So, firstly, you should be aware if your Column annotation has the runtime retention:

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

After that you can do something like this:

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

Obviously, you would like to do something with field - set new value using annotation value:

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

So, full code can be looked like this:

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()
                )
        );
}
查看更多
时光不老,我们不散
3楼-- · 2019-01-03 05:55

Yes, if your Column annotation has the runtime retention

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

you can do something like this

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

UPDATE : To get private fields use

Myclass.class.getDeclaredFields()
查看更多
我命由我不由天
4楼-- · 2019-01-03 05:56

Of course it is. Here is a sample annotation:

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

    String testText();
}

And a sample annotated method:

class TestClass {

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

And a sample method in another class that prints the value of the 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());
    }
}

Not much different for field annotations like yours.

Cheerz!

查看更多
相关推荐>>
5楼-- · 2019-01-03 05:58

You can also use generic types, in my case, taking into account everything said before you can do something like:

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

    }

}

Remember, that this will not equival at 100% to SomeClass.class.get(...)();

But can do the trick...

查看更多
Lonely孤独者°
6楼-- · 2019-01-03 05:59

I've never done it, but it looks like Reflection provides this. Field is an AnnotatedElement and so it has getAnnotation. This page has an example (copied below); quite straightforward if you know the class of the annotation and if the annotation policy retains the annotation at runtime. Naturally if the retention policy doesn't keep the annotation at runtime, you won't be able to query it at runtime.

An answer that's since been deleted (?) provided a useful link to an annotations tutorial that you may find helpful; I've copied the link here so people can use it.

Example from 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);
  }
}
查看更多
仙女界的扛把子
7楼-- · 2019-01-03 06:04

Elaborating to the answer of @Cephalopod, if you wanted all column names in a list you could use this 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());
查看更多
登录 后发表回答