java传递对函数的引用

时间:2012-10-15 11:57:52

标签: java reference

我对Java“所有值得通过”概念感到困惑。

请考虑以下代码:

class Test {
    Integer A;
    String B;
    ...

    void SetVar(Object??? var, Object value) {
        // Set A variable to the value (considering that it's possible)
    }
}

我可以通过以下代码将SetVar设置为A并将2设置为B的方式对Hi函数进行编码吗?

void Init() {
    SetVar(this.A, 2);
    SetVar(this.B, "Hi");
}

7 个答案:

答案 0 :(得分:2)

是的,你可以。通过使用反射java api。

class Test{
    void SetVar(Field field, Object value) throws 
                       IllegalArgumentException,IllegalAccessException {
         field.set(this, value);
    }

    public static void main(String[] args){
     Test test =new Test();
         test.SetVar(Test.class.getDeclaredField("A"), 2);
         test.SetVar(Test.class.getDeclaredField("B"), "Hi");
    }
  }

答案 1 :(得分:2)

简而言之,将值(与=运算符有意义)重新分配给现有引用不会更改指向原始引用的对象。

在Java中被误解的是,人们认为它们是两种类型的变量:

  • 基元(如int,boolean等...)
  • 引用(如整数,布尔值,自定义对象等...)

Java 从不使用引用。 参考这个词用词不当。

Java仅使用指针来操作对象。

为了更好地理解阴影:http://javadude.com/articles/passbyvalue.htm

关于你的情况,即使你跳过Java命名约定(但它是另一个主题),你可以通过这样做来解决你的“问题”:

void SetVar(Integer value) {
        this.A = value;
}

实际上,如果您将A作为本地参数传递(就像您所做的那样),那么这个本地参数将代表A引用的副本,因为Java只是专注于在passed-by-value。因此,更改它不会影响初始参考。

答案 2 :(得分:1)

一般来说,这取决于。在这种特殊情况下,A和B是不可变的,你不能。

如果你有一个带有setter的可变对象,你可以在setVar方法中改变它的一些属性:

var.setValue(value);

但是你无法改变原始对象指向的引用(因为它已经通过值传递)。

var = someOtherObject; //no effect on the reference in the calling code

有关this post的更多信息,它是Java FAQ的一部分。

答案 3 :(得分:1)

是的,Java是按值传递的,但您还必须意识到,当您将对象传递给某个方法时,实际上是将一个引用(指针)传递给该对象。在您的情况下,两个参数AB也是不可变的,这意味着您只能重新分配代表它们的局部变量,而不是替换传递给{{1}的原始对象。 }。

答案 4 :(得分:0)

void SetVar(Object??? var, Object value) {

成为

void SetVar(final Integer var, final String value) {
   A=var; // use minuscule for field like  a=var;
   B=value; // this. is not necessary here
}

在构造函数中初始化:

Test (final Integer var, final String value){
   setVar(var, value);
} 

答案 5 :(得分:0)

IntegerString是不可变的,因此您无法在初始化后更改AB的值,只需为变量指定一个新值即可。因为一旦在SetVar内,变量var是方法的本地变量,更改var指向的对象不会影响外部调用者。

答案 6 :(得分:0)

你不能这样做,因为在你的例子中你传递this.A到setVar()方法,而this.A是null,所以这没用。但你可以做的就是拥有它。作为一个持有者,并将持有者传递给setVar()方法。

以下代码可以满足您的需求。它为字段a和b使用IntegerHolder和StringHolder,并在构造具有空的holder对象的类时初始化holder字段。

调用setVar()然后不设置字段a和b的值,而是设置持有者的内容。

public class Test
{
    IntegerHolder a = new IntegerHolder();
    StringHolder b = new StringHolder();

    void setVar(IntegerHolder var, Integer value) {
        var.value = value;
    }

    void setVar(StringHolder var, String value) {
        var.value = value;
    }

    class IntegerHolder
    {
        Integer value;
    }

    class StringHolder
    {
        String value;
    }

}