groovy-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Jochen Theodorou (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (GROOVY-8555) The private keyword of an instance variable is causing a behavior change in a map class
Date Sat, 21 Apr 2018 07:47:00 GMT

    [ https://issues.apache.org/jira/browse/GROOVY-8555?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16446675#comment-16446675
] 

Jochen Theodorou commented on GROOVY-8555:
------------------------------------------

x.y is using property access logic in Groovy, not field access logic, field access is done
via @, in like x.@y.
This means your cloned.a is a property access.

On a map property access sets the content of a map, unless there is an explicit property defined.

String a = 'a';
in your class defines property a, thus clone.a=... will not write the map, it will write the
property.Similar println(cloned.a) will read the property

private String a = 'a';
in your class defines no property a, only the field, thus clone.a=... will write an entry
into the map. Similar println(cloned.a) will read the map.



> The private keyword of an instance variable is causing a behavior change in a map class
> ---------------------------------------------------------------------------------------
>
>                 Key: GROOVY-8555
>                 URL: https://issues.apache.org/jira/browse/GROOVY-8555
>             Project: Groovy
>          Issue Type: Bug
>    Affects Versions: 2.4.12
>            Reporter: Howard
>            Assignee: Jochen Theodorou
>            Priority: Major
>
> h1. Problem: Adding the private keyword causes a difference in behavior when using the
dot operator
> Consider the following 2 scripts with the same class (1 with the instance variable declared
as private with everything else being the same)
> h2. Script 1:
> {code:java}
> import java.util.concurrent.ConcurrentHashMap
> import groovy.transform.CompileStatic
> class mymap<K,V> extends ConcurrentHashMap<K,V>{
>     private String a = 'a';
>     def cloned(){
>         def clone = new mymap<K,V>()
>         clone.putAll(this)
>         clone.a = this.a
>         return clone
>     }
> }
> def mm = new mymap<String, String>()
> def fieldA = mymap.class.getDeclaredField("a")
> fieldA.setAccessible(true)
> mm.b = 'b'
> def cloned = mm.cloned()
> println(cloned.a)
> println(fieldA.get(cloned))
> println(cloned)
>  {code}
> h2. Output:
> {code}
> a
> a
> [a:a, b:b]
> {code}
> h2. Script 2:
> {code}
> import java.util.concurrent.ConcurrentHashMap
> import groovy.transform.CompileStatic
> class mymap<K,V> extends ConcurrentHashMap<K,V>{
>     String a = 'a';
>     def cloned(){
>         def clone = new mymap<K,V>()
>         clone.putAll(this)
>         clone.a = this.a
>         return clone
>     }
> }
> def mm = new mymap<String, String>()
> def fieldA = mymap.class.getDeclaredField("a")
> fieldA.setAccessible(true)
> mm.b = 'b'
> def cloned = mm.cloned()
> println(cloned.a)
> println(fieldA.get(cloned))
> println(cloned)
> {code}
> h2. Output:
> {code}
> null
> a
> [b:b]
> {code}
> h1. Expectation
> Adding the 'private' keyword in front of the instance variable should not change the
output of these 2 scripts



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Mime
View raw message