注释如何防止数组参数发生突变?

时间:2018-11-22 18:59:02

标签: java arrays annotations immutability

我知道注释是不可变的,但是Java中的数组本身并不是不可变的。运行测试后,我注意到从注释参数返回的数组可以被更改,但不会影响源数组:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface ArrayAnnotation {
    String[] value() default {};
}

@ArrayAnnotation({"foo"})
public class Main {
    public static void main(String[] args) {
        ArrayAnnotation test = Main.class.getAnnotation(ArrayAnnotation.class);

        String[] test0 = test.value();
        test0[0] = "bar";
        System.out.println(test0[0]);

        String[] test1 = test.value();
        System.out.println(test1[0]);
    }
}

此打印:

bar
foo

这里的幕后发生了什么?每次调用value()时是否只是发生数组复制,还是更复杂?

2 个答案:

答案 0 :(得分:13)

  

在每次调用value()时是否只是在进行数组复制,还是更复杂?

是的,数组已复制。


注释是一种特殊的interface类型。 (JLS

它们在运行时由某些Proxy类实现。 如果您在Proxy.newProxyInstance()处设置断点,则可以对其进行调试。

注释的调用被复制数组的AnnotationInvocationHandler拦截:

if (result.getClass().isArray() && Array.getLength(result) != 0)
     result = cloneArray(result);

答案 1 :(得分:5)

您是对的,它每次都会返回一个副本以确保它未被更改。

在Java的未来版本中,此副本可能已被优化。