Maison > Java > javaDidacticiel > Pouvons-nous modifier les valeurs des paramètres d'annotation Java au moment de l'exécution ?

Pouvons-nous modifier les valeurs des paramètres d'annotation Java au moment de l'exécution ?

Patricia Arquette
Libérer: 2024-12-27 00:19:15
original
170 Les gens l'ont consulté

Can We Modify Java Annotation Parameter Values at Runtime?

Comment modifier les valeurs des paramètres d'annotation au moment de l'exécution

Énoncé du problème

Considérez une classe compilée avec une annotation définie comme suit :

@Something(someProperty = "some value")
public class Foobar {
    //...
}
Copier après la connexion

Sans modifier le code source, pouvons-nous modifier la valeur de "someProperty" au moment de l'exécution en une valeur différente valeur, de sorte qu'une réflexion ultérieure récupérera la valeur mise à jour au lieu de la valeur par défaut ?

Solution

Avis de non-responsabilité : La solution peut ne pas être applicable sur toutes les plateformes (par exemple, macOS ).

Approche :

Exploiter la réflexion des annotations de Java mécanisme, nous pouvons modifier dynamiquement les valeurs d'annotation sous-jacentes en manipulant ses structures de données internes.

Code :

/**
 * Modifies the specified annotation's key with the new value and returns the previous value.
 */
@SuppressWarnings("unchecked") // Suppress unchecked type warning for convenience
public static Object changeAnnotationValue(Annotation annotation, String key, Object newValue) {
    Object handler = Proxy.getInvocationHandler(annotation); // Obtain InvocationHandler for the annotation

    Field memberValuesField;
    try {
        memberValuesField = handler.getClass().getDeclaredField("memberValues"); // Fetch "memberValues" field
    } catch (NoSuchFieldException | SecurityException e) {
        throw new IllegalStateException(e);
    }

    memberValuesField.setAccessible(true); // Make field accessible

    Map<String, Object> memberValues;
    try {
        memberValues = (Map<String, Object>) memberValuesField.get(handler); // Obtain member values map
    } catch (IllegalArgumentException | IllegalAccessException e) {
        throw new IllegalStateException(e);
    }

    Object oldValue = memberValues.get(key); // Get the old value

    if (oldValue == null || oldValue.getClass() != newValue.getClass()) { // Ensure type safety
        throw new IllegalArgumentException();
    }

    memberValues.put(key, newValue); // Set the new value
    return oldValue; // Return the old value
}
Copier après la connexion

Exemple d'utilisation :

@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) {
    ClassAnnotation classAnnotation = TestClass.class.getAnnotation(ClassAnnotation.class);
    System.out.println("Old ClassAnnotation: " + classAnnotation.value());

    changeAnnotationValue(classAnnotation, "value", "another value");

    System.out.println("Modified ClassAnnotation: " + classAnnotation.value());

    // Modify field and method annotations similarly
}
Copier après la connexion

Avantages :

  • Pas besoin de créer une nouvelle annotation instance
  • Ne nécessite pas de connaissance préalable de la classe d'annotation concrète
  • Effets secondaires minimes car il fonctionne sur l'instance d'annotation d'origine

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal