How do annotations prevent mutations of an array parameter?











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

      favorite
      1









      up vote
      11
      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 12 hours ago

























      asked 12 hours ago









      flakes

      6,33011849




      6,33011849
























          2 Answers
          2






          active

          oldest

          votes

















          up vote
          6
          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





















          • 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
            11 hours ago




















          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
            11 hours ago











          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
          6
          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





















          • 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
            11 hours ago

















          up vote
          6
          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





















          • 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
            11 hours ago















          up vote
          6
          down vote



          accepted







          up vote
          6
          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 11 hours ago









          caco3

          7961415




          7961415












          • 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
            11 hours ago




















          • 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
            11 hours ago


















          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
          11 hours ago






          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
          11 hours ago














          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
            11 hours ago















          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
            11 hours ago













          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 11 hours ago









          Peter Lawrey

          437k55550948




          437k55550948












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


















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
















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




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


















           

          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

          flock() on closed filehandle LOCK_FILE at /usr/bin/apt-mirror

          Mangá

          Eduardo VII do Reino Unido