Rumah >Java >javaTutorial >Bolehkah Nilai Parameter Anotasi Diubah Suai pada Runtime di Java?

Bolehkah Nilai Parameter Anotasi Diubah Suai pada Runtime di Java?

Linda Hamilton
Linda Hamiltonasal
2024-12-11 18:51:15361semak imbas

Can Annotation Parameter Values Be Modified at Runtime in Java?

Ubah suai Nilai Parameter Anotasi pada Masa Jalan

Bayangkan menghadapi kelas dengan anotasi yang dihiasi dengan nilai parameter tertentu dan anda ingin mengubahnya nilai semasa runtime. Adakah boleh untuk menukar nilai parameter anotasi dalam kelas terkumpul yang telah dimuatkan ke dalam JVM?

Penyelesaian:

Ya, adalah mungkin untuk mengubah suai parameter anotasi nilai semasa runtime. Pendekatan berikut boleh digunakan:

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

Penggunaan:

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

Pendekatan ini beroperasi dengan mengubah suai secara langsung perwakilan dalaman anotasi. Akibatnya, panggilan refleksi seterusnya akan mendapatkan semula nilai parameter yang diubah. Ia mempunyai kelebihan kerana tidak memerlukan penciptaan contoh anotasi baharu, yang menghapuskan keperluan untuk pengetahuan terdahulu tentang kelas anotasi khusus. Selain itu, dengan membiarkan contoh anotasi asal tidak disentuh, ia meminimumkan kesan sampingan.

Atas ialah kandungan terperinci Bolehkah Nilai Parameter Anotasi Diubah Suai pada Runtime di Java?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn