Java - 在匿名方法中更改参数对象
Java - Change a parameter object inside anonymous method
我今天遇到了这个,我不太明白发生了什么。
目的是创建一个可以更改参数对象的匿名方法。我虽然想出了一种聪明的方法来传递值并在不同对象之间修改它们,而无需明确了解另一个对象,但有些地方出了问题。
以下代码概述了一般问题:
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);
}
我的本意是这段代码应该输出 bar,但它输出 foo。我不太清楚为什么。 Java-objects 不是通过引用传递的吗?那样的话,难道我不能修改它们吗?
有人可以解释一下我错过了什么吗?
我对该领域术语的了解实际上可能限制了我在线搜索此内容的能力,因为我不知道要用什么词 Google。
谢谢 // 西蒙
Java 始终按值传递。除了在声明它的方法中重新分配它之外,您根本无法更改局部变量指向的内容。与其他一些语言不同,您不能传递 a
"by reference" 并让另一个方法更新它指向的内容。
通过指定 arg[0] = "bar"
,您已成功将值 "bar"
分配给参数数组的第一个元素。但这对 a
.
没有影响
参见:
- Is Java "pass-by-reference" or "pass-by-value"?
args[]
是匿名 MethodMap 实例中的局部变量,它指的是隐式创建的临时数组,用于保存 .invoke(...)
调用的额外参数。
分配 args[0]
时,您所做的只是更新临时数组。
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);
}
我今天遇到了这个,我不太明白发生了什么。
目的是创建一个可以更改参数对象的匿名方法。我虽然想出了一种聪明的方法来传递值并在不同对象之间修改它们,而无需明确了解另一个对象,但有些地方出了问题。 以下代码概述了一般问题:
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);
}
我的本意是这段代码应该输出 bar,但它输出 foo。我不太清楚为什么。 Java-objects 不是通过引用传递的吗?那样的话,难道我不能修改它们吗?
有人可以解释一下我错过了什么吗?
我对该领域术语的了解实际上可能限制了我在线搜索此内容的能力,因为我不知道要用什么词 Google。
谢谢 // 西蒙
Java 始终按值传递。除了在声明它的方法中重新分配它之外,您根本无法更改局部变量指向的内容。与其他一些语言不同,您不能传递 a
"by reference" 并让另一个方法更新它指向的内容。
通过指定 arg[0] = "bar"
,您已成功将值 "bar"
分配给参数数组的第一个元素。但这对 a
.
参见:
- Is Java "pass-by-reference" or "pass-by-value"?
args[]
是匿名 MethodMap 实例中的局部变量,它指的是隐式创建的临时数组,用于保存 .invoke(...)
调用的额外参数。
分配 args[0]
时,您所做的只是更新临时数组。
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);
}