7

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

我认为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.

4

4 回答 4

22

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

最初你有这个:

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

当您第一次输入方法 setNotNull 时,您将获得nullTest in值的副本s。在这种情况下, nullTest 的值是一个空引用:

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

然后重新分配 s:

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

然后离开方法:

------------
| nullTest |
------------
     |
    null
于 2010-08-14T00:25:34.807 回答
2

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

于 2010-08-14T00:25:40.733 回答
1

我希望在不使用 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());

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

于 2010-08-14T03:03:51.563 回答
0
s =

这就是为什么。您正在分配给 s,而不是修改 s 指向的对象。

于 2010-08-14T00:28:41.387 回答