java向函数传递引用

java向函数传递引用,java,reference,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) } } 我是否可以按照以下代码将A设置为2和B设置为Hi的方式对SetVar功能进行编码 v

我对Java的“所有值传递”概念有点困惑

考虑以下代码:

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

    void SetVar(Object??? var, Object value) {
        // Set A variable to the value (considering that it's possible)
    }
}
我是否可以按照以下代码将
A
设置为
2
B
设置为
Hi
的方式对
SetVar
功能进行编码

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

一般来说,这要视情况而定。在这种特殊情况下,A和B是不可变的,您不能

如果您有一个带有setter的可变对象,您可以在
setVar
方法中对其某些属性进行变异:

var.setValue(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);
} 

Integer
String
是不可变的,因此不能更改
A
B
的值初始化后,只需为变量指定一个新值即可。由于一旦进入
SetVar
内部,变量
var
就属于方法的局部变量,因此更改
var
所指向的对象不会影响外部调用方。

是的,Java是按值传递的,但您还必须意识到,当您将对象传递给某个方法时,实际上是在传递引用(指针)对那个目标。在您的例子中,两个参数
A
B
也是不可变的,这意味着您只能重新分配表示它们的局部变量,而不是替换传递到
SetVar
的原始对象。通过使用反射javaapi

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

简而言之,将值(使用
=
运算符)重新指定给现有引用不会更改原始引用指向的对象

Java中一个很大的误解是人们认为它们是两种类型的变量:

  • 原语(如int、boolean等)
  • 引用(如整数、布尔值、自定义对象等)
Java从不使用引用。“参考”一词用词不当

Java只使用指针来操作对象

为了更好地理解阴影:

关于您的案例,尽管您跳过了Java命名约定(但这是另一个主题),但您可以通过以下方式解决“问题”:

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

事实上,如果您将
A
作为本地参数传递(正如您所做的那样),那么这个本地参数将表示
A
引用的副本,因为Java只关注
按值传递的
。因此,更改它不会影响初始引用。

您不能这样做,因为在您的示例中,您正在将此.A传递给setVar()方法,而此.A为null,因此这没有用处。但是,您可以做的是让.A成为一个holder,并将该holder传递给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;
    }

}

不,你不能那样做。您正在将A的值传递给方法,该值可能为null。因此,您正在传递(null,2)和(null,“Hi”),这不是很有用。请遵循。即使是名称问题,C和Java中的指针也不是相同的可能性:它们是不可修改的,不能直接访问内存,因此对于非数学家来说,引用确实是一个很好的答案,即使它闻起来对你不好academician@cl-r是的,完全同意。但是你的解释更深刻,我认为会超过基本的解释。如果他们能混合使用指针和引用来更改名称会更好,为什么不使用“poinref”^^在法语中,单词“référence”和动作“faire référenceéquelque select”(引用某物)正是常见的挖掘。poinref可能很好,可能是
引用人
,持有引用的“个人/演员”?
void SetVar(Integer value) {
        this.A = value;
}
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;
    }

}