Modify a class definition's annotation string parameter at runtime

后端 未结 7 1765
[愿得一人]
[愿得一人] 2020-11-22 04:55

Imagine there is a class:

@Something(someProperty = \"some value\")
public class Foobar {
    //...
}

Which is already compiled (I cannot c

7条回答
  •  伪装坚强ぢ
    2020-11-22 05:22

    This code does more or less what you ask for - it is a simple proof of concept:

    • a proper implementation needs to also deal with the declaredAnnotations
    • if the implementation of annotations in Class.java changes, the code will break (i.e. it can break at any time in the future)
    • I have no idea if there are side effects...

    Output:

    oldAnnotation = some value
    modifiedAnnotation = another value

    public static void main(String[] args) throws Exception {
        final Something oldAnnotation = (Something) Foobar.class.getAnnotations()[0];
        System.out.println("oldAnnotation = " + oldAnnotation.someProperty());
        Annotation newAnnotation = new Something() {
    
            @Override
            public String someProperty() {
                return "another value";
            }
    
            @Override
            public Class annotationType() {
                return oldAnnotation.annotationType();
            }
        };
        Field field = Class.class.getDeclaredField("annotations");
        field.setAccessible(true);
        Map, Annotation> annotations = (Map, Annotation>) field.get(Foobar.class);
        annotations.put(Something.class, newAnnotation);
    
        Something modifiedAnnotation = (Something) Foobar.class.getAnnotations()[0];
        System.out.println("modifiedAnnotation = " + modifiedAnnotation.someProperty());
    }
    
    @Something(someProperty = "some value")
    public static class Foobar {
    }
    
    @Retention(RetentionPolicy.RUNTIME)
    @interface Something {
    
        String someProperty();
    }
    

提交回复
热议问题