问题
Is it possible in Java (or Groovy) to pass an object by reference into a wrapper object (ie: List or Map)?
Example code (in Groovy):
def object = null
def map = [object: object]
object = new Object()
Unfortunately map.object remains null even though the object variable doesn't, so obviously the original creation of the map was done by value not by reference.
Is it possible to create a List or Map via references so that when the object outside the List or Map changes the change is reflected inside the wrapper object?
回答1:
No, you can't really do that. Depending on what you are really trying to do, something like this might help:
class MyWrapper {
def wrappedValue
}
def object = new MyWrapper()
def map = [object: object]
object.wrappedValue = 'This is a new value'
assert map.object.wrappedValue == 'This is a new value'
That of course is Groovy code. You can do the same sort of thing in Java, just with a little more code. The idea would be the same.
回答2:
You can with closures, but they need to be invoked:
def object = null
def map = [object: { object }]
object = new Object()
assert map.object() != null
回答3:
In Java (and I assume in Groovy too), when you pass an object - you pass the value of the reference to it.
So for example when you do this:
Object reference1 = new Object();
// reference1 now equals some adress in memory, e.g. 0001
Object reference2 = reference1;
// reference2 now equals the value of reference1 - i.e. 0001
Now, when we do this:
reference1 = new Dog();
// reference1 is now assigned a new value, which is the memory adress
// of the new Dog object.
There is no reason for it to affect reference2
. reference2
still holds the adress 0001
. And that's exactly what you're doing.
Let's examine what's happening in the piece of code you posted:
def object = null
A new reference named object
is created, and assigned no adresss, i.e. null
. (No object is created, only a reference).
def map = [object: object]
A new reference named map
is created. It is assigned a new map object, with an entry named object
. The map is passed the value of the reference named object
.
As you remember, the value of the object
reference is currently null
. So this value is passed (i.e. pass-by-value) to the reference in the map object, which now holds null
too.
object = new Object()
The reference object
in the main program is assigned a new value - a new Object
. It now holds the adress of the new object, e.g. 0001
.
When you do this, you put a value in the object
variable - you put an adress of an object (where was previously null
).
If you think about it, there's no reason for it to affect the map. The map has a completely different reference. Just becasue previously both references held the same adress memory, i.e. referenced the same object (or in this case, no object since the adress was null
), doesn't mean that when the value of one reference is changed (i.e. it's assigned a different value in memory), the value of the other has to change too.
This is an important distinction between an object and a reference.
来源:https://stackoverflow.com/questions/25329428/groovy-or-java-pass-by-reference-into-a-wrapper-object