Maison >Java >javaDidacticiel >Les valeurs des paramètres d'annotation peuvent-elles être modifiées lors de l'exécution en Java ?
Modifier les valeurs des paramètres d'annotation au moment de l'exécution
Imaginez rencontrer une classe avec une annotation décorée avec une valeur de paramètre spécifique et vous souhaitez la modifier valeur au moment de l’exécution. Est-il possible de modifier la valeur d'un paramètre d'annotation dans une classe compilée déjà chargée dans la JVM ?
Solution :
Oui, il est possible de modifier le paramètre d'annotation valeurs au moment de l’exécution. L'approche suivante peut être employée :
@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<String, Object> memberValues; try { memberValues = (Map<String, Object>) 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; }
Utilisation :
@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()); }
Cette approche fonctionne en modifiant directement la représentation interne de l'annotation. En conséquence, les appels de réflexion ultérieurs récupéreront la valeur du paramètre modifié. Il présente l’avantage de ne pas nécessiter la création d’une nouvelle instance d’annotation, ce qui élimine le besoin de connaissance préalable de la classe d’annotation spécifique. De plus, en laissant l'instance d'annotation d'origine intacte, cela minimise les effets secondaires.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!