Pertimbangkan kelas yang disusun dengan anotasi yang ditakrifkan seperti berikut:
@Something(someProperty = "some value") public class Foobar { //... }
Tanpa mengubah kod sumber, bolehkah kita mengubah suai nilai "someProperty" pada masa jalan kepada nilai yang berbeza, supaya refleksi seterusnya akan mendapatkan semula nilai yang dikemas kini dan bukannya lalai?
Penafian: Penyelesaian mungkin tidak terpakai pada semua platform (mis., macOS).
Pendekatan:
Memanfaatkan mekanisme refleksi anotasi Java, kami boleh mengubah suai nilai anotasi asas secara dinamik dengan memanipulasi data dalamannya struktur.
Kod:
/** * 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 }
@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 }
Atas ialah kandungan terperinci Bolehkah Kami Mengubah Suai Nilai Parameter Anotasi Java pada Runtime?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!