为什么我的 Java 方法无法更改传递的变量?[复制]

Why can't my Java method change a passed variable? [duplicate]

提问人:Will 提问时间:8/14/2010 最后编辑:Paŭlo EbermannWill 更新时间:8/24/2011 访问量:7256

问:

当我看到以下代码没有按预期工作时,我有点困惑。

我以为 Java 总是通过引用将变量传递到函数中。因此,为什么函数不能重新分配变量?

public static void main(String[] args) {

  String nullTest = null;

  setNotNull(nullTest);

  System.out.println(nullTest);
}

private static void setNotNull(String s) {
  s = "not null!";
}

此程序输出 .null

Java 变量 null 传递

评论

0赞 user207421 8/14/2010
这并不意味着什么。您可以实例化任何可以实例化的内容,但不能更改调用方传递给您的值。

答:

22赞 Mark Byers 8/14/2010 #1

在 Java 中,对对象的引用是按传递的,因此分配给方法内部的局部变量不会更改原始变量。只有局部变量指向新字符串。用一点 ASCII 艺术可能更容易理解。s

最初你有这个:

------------
| nullTest |
------------
     |
    null

首次输入方法 setNotNull 时,将获得 中 nullTest 值的副本。在本例中,nullTest 的值为 null 引用:s

------------    ------------
| nullTest |    |    s     |
------------    ------------
     |               |
    null            null

然后重新分配 s:

------------    ------------
| nullTest |    |    s     |
------------    ------------
     |               |
    null         "not null!"

然后离开方法:

------------
| nullTest |
------------
     |
    null

评论

0赞 TheLQ 8/14/2010
那么对象呢?我得到了一个带有大反菜鸟态度的通用答案,但还没有得到很好的解释
0赞 raja kolluru 8/14/2010
展示内存结构的好方法。+1
0赞 raja kolluru 8/14/2010
@ Lord.Quackster:java 处理对象的方式与原始类型没有区别。两者都按值传递。但是,由于 java 使用对象的“引用”进行操作,因此可以改变传递的引用。但是,由于引用本身是按值传递的,因此无法将引用重置为其他内容。
0赞 Marsellus Wallace 8/24/2011
@TheLQ:我想说的是,Java 是通过变量值的复制来传递的。在原语的情况下,复制的值是值本身;对于对象,复制的值是告诉 JVM 如何在堆内存中检索对象的东西。在谈论这个问题时,我不喜欢使用 Strings,因为它们是不可变的(String 仍然是一个对象)。更多在这里: stackoverflow.com/questions/40480/is-java-pass-by-reference/...
3赞 akf 8/14/2010 #2

Java 不通过引用传递,而是传递引用的值。在分配 时,您将重新分配该值。s="not null"

0赞 Bwmat 8/14/2010 #3
s =

这就是原因。您正在分配给 S,而不是修改 S 指向的对象。

1赞 Stephen C 8/14/2010 #4

我希望在不使用 o = setNotNull(o) 的情况下做类似 setNotNull(MyObject o) 的事情

简单地说,你不能。你最接近的是这样的:

public class MyRef<T> {
    private T obj;

    public T get() {
        return obj;
    }

    public void set(T obj) {
        this.obj = obj;
    }

    public void setNotNull(T obj) {
        if (this.obj == null) {
            this.obj = obj;
        }
    }
}

MyRef<MyObj> ref = new MyRef<MyObj>();
ref.setNotNull(xyz);
System.err.println(ref.get());

这一切都相当笨拙,可能不值得付出努力。