How do annotations prevent mutations of an array parameter?











up vote
15
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
    15
    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
      15
      down vote

      favorite
      1









      up vote
      15
      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 Nov 22 at 19:05

























      asked Nov 22 at 18:59









      flakes

      6,48411850




      6,48411850
























          2 Answers
          2






          active

          oldest

          votes

















          up vote
          12
          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
            Nov 22 at 19:23




















          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
            Nov 22 at 19:24











          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
          12
          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
            Nov 22 at 19:23

















          up vote
          12
          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
            Nov 22 at 19:23















          up vote
          12
          down vote



          accepted







          up vote
          12
          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 Nov 22 at 19:17









          caco3

          9501417




          9501417








          • 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
            Nov 22 at 19:23
















          • 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
            Nov 22 at 19:23










          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
          Nov 22 at 19:23






          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
          Nov 22 at 19:23














          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
            Nov 22 at 19:24















          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
            Nov 22 at 19:24













          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 Nov 22 at 19:16









          Peter Lawrey

          438k55556952




          438k55556952












          • Yeah, I was thinking that it seems pretty expensive to copy the array every time that it is viewed!
            – flakes
            Nov 22 at 19:24


















          • Yeah, I was thinking that it seems pretty expensive to copy the array every time that it is viewed!
            – flakes
            Nov 22 at 19:24
















          Yeah, I was thinking that it seems pretty expensive to copy the array every time that it is viewed!
          – flakes
          Nov 22 at 19:24




          Yeah, I was thinking that it seems pretty expensive to copy the array every time that it is viewed!
          – flakes
          Nov 22 at 19:24


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          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

          mysqli_query(): Empty query in /home/lucindabrummitt/public_html/blog/wp-includes/wp-db.php on line 1924

          How to change which sound is reproduced for terminal bell?

          Can I use Tabulator js library in my java Spring + Thymeleaf project?