Java - changing a parameter object inside an anonymous method

Today I came across this and I canโ€™t understand what is happening.

The goal is to create an anonymous method that can modify argument objects. I, although I came up with a smart way to transfer values โ€‹โ€‹and change them between different objects without explicit knowledge of another object, but something is wrong. The following code describes a common problem:

void foo() { String a = "foo"; MethodMap.addMethod("1", new Method() { @Override public void execute(Object ... args) { args[0] = "bar"; } } ); MethodMap.invoke("1", a); System.out.println(a); } class MethodMap { private static Map<String, Invocation> map = new HashMap<>(); public static boolean addMethod(String key, Invocation method) { map.put(key, method); } public static void invoke(String key, Object ... args){ map.get(key).execute(args); } } public interface Invocation { public void execute(Object ... args); } 

My intention was that this code should output a bar, but it outputs foo. I'm not quite sure why. Are Java objects passed by reference? In that case, can I change them?

Can someone explain what I am missing?

My knowledge of terminology in this area may indeed be what limits my ability to search this online, because I have no idea what words are for Google.

Thanks // Simon

+4
source share
2 answers

Java is always passed by value. You simply cannot change what a local variable indicates except to reassign it in the method in which it is declared. Unlike some other languages, you cannot pass a โ€œby referenceโ€ and another way to update what it points to.

By specifying arg[0] = "bar" , you successfully assign the value "bar" first element of your parameter array. But this does not affect a .

See:

+5
source

args[] is a local variable in your anonymous MethodMap instance and refers to a temporary array that was implicitly created to hold additional arguments for calling .invoke(...) .

Everything you do when you assign args[0] updates the temporary array.


 void foo() { // a is a local variable in your foo() method that refers to an // immutable String object with the value, "foo". String a = "foo"; MethodMap.addMethod("1", new Method() { @Override // args is a local variable in the execute() method, that refers // to a temporary Array object. public void execute(Object ... args) { // This assignment changes the zeroth element of the temporary // array to point to a String object with the value, "bar". args[0] = "bar"; } } ); // The compiler turns your MethodMap.invoke() call into this: // Array<Object> tmp = new Array<Object>[1]; // tmp[0] = a; // tmp[0] now refers to the same immutable String as a. // MethodMap.invoke("1", tmp); // The tmp array is ignored after the invoke call returns. MethodMap.invoke("1", a); System.out.println(a); } 
+1
source

All Articles