Groovy (or Java) - Pass by reference into a wrapper object

偶尔善良 提交于 2021-01-28 06:21:01

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!