[java] 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”)의 값을 다른 클래스에서 읽을 수 있습니까?



답변

예, 열 주석에 런타임 보존이있는 경우

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

업데이트 : 개인 필드를 사용하려면

Myclass.class.getDeclaredFields()


답변

당연하지. 다음은 샘플 주석입니다.

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

귀하와 같은 필드 주석의 경우 크게 다르지 않습니다.

치어 즈!


답변

나는 그것을 한 적이 없지만 Reflection 이 이것을 제공 하는 것처럼 보입니다 . Field입니다 AnnotatedElement그리고 그것은있다 getAnnotation. 이 페이지 에는 예제가 있습니다 (아래 복사). 주석의 클래스를 알고 있고 주석 정책이 런타임에 주석을 유지한다면 매우 간단합니다. 당연히 보존 정책이 주석을 런타임에 유지하지 않으면 런타임에 쿼리 할 수 ​​없습니다.

이후 삭제 된 답변 (?)은 유용한 주석 자습서에 대한 유용한 링크를 제공했습니다 . 사람들이 사용할 수 있도록 여기에 링크를 복사했습니다.

이 페이지의 예 :

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


답변

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


답변

지금까지 제공된 모든 답변은 완벽하게 유효하지만 주석 스캔에 대한보다 일반적이고 쉬운 접근 방식을 위해 Google Reflections 라이브러리 를 염두에 두어야합니다.

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

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


답변

제 경우에는 다음과 같은 작업을 수행하기 전에 말한 모든 것을 고려하여 제네릭 유형을 사용할 수도 있습니다.

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

    }

}

이것은 SomeClass.class.get (…) ();과 100 % 동일하지 않다는 것을 기억하십시오.

하지만 트릭을 할 수 있습니다 …


답변

일반적인 경우에는 필드에 대한 개인 액세스 권한이 있으므로 리플렉션에 getFields 를 사용할 수 없습니다 . 대신에 getDeclaredFields 를 사용해야합니다.

따라서 먼저 Column 주석에 런타임 보존이 있는지 알아야합니다.

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