How do annotations prevent mutations of an array parameter?











up vote
13
down vote

favorite
1












I understand that annotations are immutable, however, arrays in Java are by themselves not immutable. After running a test I notice that the array returned from an annotation parameter can be mutated but it does not effect the source array:



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


This prints:



bar
foo


What is going on behind the scenes here? Is there simply an array copy happening during each call to value(), or is it something more complex?










share|improve this question




























    up vote
    13
    down vote

    favorite
    1












    I understand that annotations are immutable, however, arrays in Java are by themselves not immutable. After running a test I notice that the array returned from an annotation parameter can be mutated but it does not effect the source array:



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


    This prints:



    bar
    foo


    What is going on behind the scenes here? Is there simply an array copy happening during each call to value(), or is it something more complex?










    share|improve this question


























      up vote
      13
      down vote

      favorite
      1









      up vote
      13
      down vote

      favorite
      1






      1





      I understand that annotations are immutable, however, arrays in Java are by themselves not immutable. After running a test I notice that the array returned from an annotation parameter can be mutated but it does not effect the source array:



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


      This prints:



      bar
      foo


      What is going on behind the scenes here? Is there simply an array copy happening during each call to value(), or is it something more complex?










      share|improve this question















      I understand that annotations are immutable, however, arrays in Java are by themselves not immutable. After running a test I notice that the array returned from an annotation parameter can be mutated but it does not effect the source array:



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


      This prints:



      bar
      foo


      What is going on behind the scenes here? Is there simply an array copy happening during each call to value(), or is it something more complex?







      java arrays annotations immutability






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited yesterday

























      asked yesterday









      flakes

      6,46511850




      6,46511850
























          2 Answers
          2






          active

          oldest

          votes

















          up vote
          10
          down vote



          accepted











          Is there simply an array copy happening during each call to value(), or is it something more complex?




          Yes, the array is copied.





          Annotations are a special kind of interface type. (JLS)



          They are implemented by some Proxy classes at runtime.
          You can debug it if you set breakpoint at Proxy.newProxyInstance().



          Invocations on annotation are intercepted by AnnotationInvocationHandler which copies arrays:



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





          share|improve this answer

















          • 1




            Ah, very cool! The step-into feature in my IDE's debugger wasn't triggering anything for values() but adding a breakpoint directly in the AnnotationInvocationHandler proxy does the trick! Thanks a lot!
            – flakes
            yesterday




















          up vote
          5
          down vote













          You are right, it returns a copy each time to ensure it is not changed.



          In a future version of Java, this copy might be optimised away.






          share|improve this answer





















          • Yeah, I was thinking that it seems pretty expensive to copy the array every time that it is viewed!
            – flakes
            yesterday











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














           

          draft saved


          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53436794%2fhow-do-annotations-prevent-mutations-of-an-array-parameter%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          2 Answers
          2






          active

          oldest

          votes








          2 Answers
          2






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          up vote
          10
          down vote



          accepted











          Is there simply an array copy happening during each call to value(), or is it something more complex?




          Yes, the array is copied.





          Annotations are a special kind of interface type. (JLS)



          They are implemented by some Proxy classes at runtime.
          You can debug it if you set breakpoint at Proxy.newProxyInstance().



          Invocations on annotation are intercepted by AnnotationInvocationHandler which copies arrays:



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





          share|improve this answer

















          • 1




            Ah, very cool! The step-into feature in my IDE's debugger wasn't triggering anything for values() but adding a breakpoint directly in the AnnotationInvocationHandler proxy does the trick! Thanks a lot!
            – flakes
            yesterday

















          up vote
          10
          down vote



          accepted











          Is there simply an array copy happening during each call to value(), or is it something more complex?




          Yes, the array is copied.





          Annotations are a special kind of interface type. (JLS)



          They are implemented by some Proxy classes at runtime.
          You can debug it if you set breakpoint at Proxy.newProxyInstance().



          Invocations on annotation are intercepted by AnnotationInvocationHandler which copies arrays:



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





          share|improve this answer

















          • 1




            Ah, very cool! The step-into feature in my IDE's debugger wasn't triggering anything for values() but adding a breakpoint directly in the AnnotationInvocationHandler proxy does the trick! Thanks a lot!
            – flakes
            yesterday















          up vote
          10
          down vote



          accepted







          up vote
          10
          down vote



          accepted







          Is there simply an array copy happening during each call to value(), or is it something more complex?




          Yes, the array is copied.





          Annotations are a special kind of interface type. (JLS)



          They are implemented by some Proxy classes at runtime.
          You can debug it if you set breakpoint at Proxy.newProxyInstance().



          Invocations on annotation are intercepted by AnnotationInvocationHandler which copies arrays:



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





          share|improve this answer













          Is there simply an array copy happening during each call to value(), or is it something more complex?




          Yes, the array is copied.





          Annotations are a special kind of interface type. (JLS)



          They are implemented by some Proxy classes at runtime.
          You can debug it if you set breakpoint at Proxy.newProxyInstance().



          Invocations on annotation are intercepted by AnnotationInvocationHandler which copies arrays:



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






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered yesterday









          caco3

          8361416




          8361416








          • 1




            Ah, very cool! The step-into feature in my IDE's debugger wasn't triggering anything for values() but adding a breakpoint directly in the AnnotationInvocationHandler proxy does the trick! Thanks a lot!
            – flakes
            yesterday
















          • 1




            Ah, very cool! The step-into feature in my IDE's debugger wasn't triggering anything for values() but adding a breakpoint directly in the AnnotationInvocationHandler proxy does the trick! Thanks a lot!
            – flakes
            yesterday










          1




          1




          Ah, very cool! The step-into feature in my IDE's debugger wasn't triggering anything for values() but adding a breakpoint directly in the AnnotationInvocationHandler proxy does the trick! Thanks a lot!
          – flakes
          yesterday






          Ah, very cool! The step-into feature in my IDE's debugger wasn't triggering anything for values() but adding a breakpoint directly in the AnnotationInvocationHandler proxy does the trick! Thanks a lot!
          – flakes
          yesterday














          up vote
          5
          down vote













          You are right, it returns a copy each time to ensure it is not changed.



          In a future version of Java, this copy might be optimised away.






          share|improve this answer





















          • Yeah, I was thinking that it seems pretty expensive to copy the array every time that it is viewed!
            – flakes
            yesterday















          up vote
          5
          down vote













          You are right, it returns a copy each time to ensure it is not changed.



          In a future version of Java, this copy might be optimised away.






          share|improve this answer





















          • Yeah, I was thinking that it seems pretty expensive to copy the array every time that it is viewed!
            – flakes
            yesterday













          up vote
          5
          down vote










          up vote
          5
          down vote









          You are right, it returns a copy each time to ensure it is not changed.



          In a future version of Java, this copy might be optimised away.






          share|improve this answer












          You are right, it returns a copy each time to ensure it is not changed.



          In a future version of Java, this copy might be optimised away.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered yesterday









          Peter Lawrey

          437k55551949




          437k55551949












          • Yeah, I was thinking that it seems pretty expensive to copy the array every time that it is viewed!
            – flakes
            yesterday


















          • Yeah, I was thinking that it seems pretty expensive to copy the array every time that it is viewed!
            – flakes
            yesterday
















          Yeah, I was thinking that it seems pretty expensive to copy the array every time that it is viewed!
          – flakes
          yesterday




          Yeah, I was thinking that it seems pretty expensive to copy the array every time that it is viewed!
          – flakes
          yesterday


















           

          draft saved


          draft discarded



















































           


          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53436794%2fhow-do-annotations-prevent-mutations-of-an-array-parameter%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          How did Captain America manage to do this?

          迪纳利

          南乌拉尔铁路局