繁体   English   中英

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对象? 在那种情况下,我不应该修改它们吗?

有人可以解释一下我错过了什么吗?

我对该领域术语的了解可能实际上限制了我在网上搜索这个术语的能力,因为我不知道谷歌会说些什么。

谢谢//西蒙

Java始终是按值传递的。 除了在声明它的方法中重新分配局部变量之外,您根本无法更改局部变量指向的内容。 其它语言不同,你无法通过a “参照”,并有另一种方法更新它所指向。

通过指定arg[0] = "bar" ,您可以成功地将值"bar"分配给参数数组的第一个元素。 但这对a没有影响。

看到:

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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM