groovy
  1. groovy
  2. GROOVY-4751

Defensive copying doesn't work for @Immutable classes

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.7.10
    • Fix Version/s: 1.8-rc-4, 1.7.11
    • Component/s: None
    • Labels:
      None
    • Testcase included:
      yes
    • Number of attachments :
      0

      Description

      Seems like @Immutable classes do not do defensive copying of the collection provided into constructor:

      @Immutable
      final class Person {
          String name
          List<String> address
      }
      
      def myAddress = ["Line1","Line2"]
      def person = new Person(name:"Name", address:myAddress)
      assert person.address == ["Line1","Line2"]
      myAddress << "Line3"
      assert myAddress == ["Line1","Line2","Line3"]
      assert person.address == ["Line1","Line2"] //<- fails
      

        Activity

        Guillaume Laforge made changes -
        Field Original Value New Value
        Summary defensive copying doesn't work for @Immutable classes Defensive copying doesn't work for @Immutable classes
        Assignee Guillaume Laforge [ guillaume ]
        Description Seems like @Immutable classes do not do defensive copying of the collection provided into constructor:

        @Immutable
        final class Person {
            String name
            List<String> address
        }

        def myAddress = ["Line1","Line2"]
        def person = new Person(name:"Name", address:myAddress)
        assert person.address == ["Line1","Line2"]
        myAddress << "Line3"
        assert myAddress == ["Line1","Line2","Line3"]
        assert person.address == ["Line1","Line2"] //<- fails
        Seems like @Immutable classes do not do defensive copying of the collection provided into constructor:
        {code}
        @Immutable
        final class Person {
            String name
            List<String> address
        }

        def myAddress = ["Line1","Line2"]
        def person = new Person(name:"Name", address:myAddress)
        assert person.address == ["Line1","Line2"]
        myAddress << "Line3"
        assert myAddress == ["Line1","Line2","Line3"]
        assert person.address == ["Line1","Line2"] //<- fails
        {code}
        Component/s ast builder [ 10444 ]
        Guillaume Laforge made changes -
        Assignee Paul King [ paulk_asert ]
        Hide
        Paul King added a comment -

        Workaround is to use ArrayList not List as the type for address.

        Show
        Paul King added a comment - Workaround is to use ArrayList not List as the type for address .
        Hide
        Paul King added a comment -

        Thanks for spotting that. Should be fixed now.

        Show
        Paul King added a comment - Thanks for spotting that. Should be fixed now.
        Paul King made changes -
        Status Open [ 1 ] Resolved [ 5 ]
        Fix Version/s 1.7.11 [ 17244 ]
        Fix Version/s 1.8-rc-4 [ 17245 ]
        Resolution Fixed [ 1 ]
        Paul King made changes -
        Status Resolved [ 5 ] Closed [ 6 ]

          People

          • Assignee:
            Paul King
            Reporter:
            Denis Solonenko
          • Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: