実行時にコメントに値を渡す

3403 ワード

実行時にコメントに値を渡す


デマンド:DeviceDataクラスに@Entityという注記があると仮定し、実行時にvalueの値を変更する必要があります.
@Entity(value="data")
public class DeviceData {
    private String deviceId;    
    private Long timestamp;    
    private String data;
// setter、getter...
}

次のコードはテストで実行できます.このコードはテストにすぎず、上記のニーズに完全に対応しているわけではありません.
/** 
* Changes the annotation value for the given key of the given annotation to newValue and returns 
* the previous value. 
*/
@SuppressWarnings("unchecked")
public static Object changeAnnotationValue(Annotation annotation, String key, Object newValue){ 
Object handler = Proxy.getInvocationHandler(annotation); 
Field f; 
  try {
     f = handler.getClass().getDeclaredField("memberValues"); 
  } catch (NoSuchFieldException | SecurityException e) { 
      throw new IllegalStateException(e); 
}
f.setAccessible(true); 
Map memberValues; 
try { 
  memberValues = (Map) f.get(handler); 
} catch (IllegalArgumentException | IllegalAccessException e) { 
throw new IllegalStateException(e); 
} 
Object oldValue = memberValues.get(key); 
if (oldValue == null || oldValue.getClass() != newValue.getClass()) { 
throw new IllegalArgumentException(); 
} 
memberValues.put(key,newValue); return oldValue;}

使用例
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ClassAnnotation { 
String value() default "";
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FieldAnnotation { 
String value() default "";
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MethodAnnotation { 
String value() default "";
}

@ClassAnnotation("class test")
public static class TestClass{ 
    @FieldAnnotation("field test") 
    public Object field; 
    @MethodAnnotation("method test") 
    public void method(){ }
}

public static void main(String[] args) throws Exception { 

final ClassAnnotation classAnnotation = TestClass.class.getAnnotation(ClassAnnotation.class); 
System.out.println("old ClassAnnotation = " + classAnnotation.value()); 
changeAnnotationValue(classAnnotation, "value", "another class annotation value"); 
System.out.println("modified ClassAnnotation = " + classAnnotation.value()); 

Field field = TestClass.class.getField("field"); 
final FieldAnnotation fieldAnnotation = 
field.getAnnotation(FieldAnnotation.class); 
System.out.println("old FieldAnnotation = " + 
fieldAnnotation.value()); 
changeAnnotationValue(fieldAnnotation, "value", "another field annotation value"); 
System.out.println("modified FieldAnnotation = " + fieldAnnotation.value()); 

Method method = TestClass.class.getMethod("method"); 
final MethodAnnotation methodAnnotation = method.getAnnotation(MethodAnnotation.class); 
System.out.println("old MethodAnnotation = " + methodAnnotation.value()); 
changeAnnotationValue(methodAnnotation, "value", "another method annotation value"); 
System.out.println("modified MethodAnnotation = " + methodAnnotation.value());}

参照リンク:http://stackoverflow.com/questions/14268981/modify-a-class-definitions-annotation-string-parameter-at-runtime