【问题标题】:Why can't my Java method change a passed variable? [duplicate]为什么我的 Java 方法不能更改传递的变量? [复制]
【发布时间】:2011-03-29 17:29:02
【问题描述】:

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

我认为 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 variables null pass-by-reference pass-by-value


【解决方案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());

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

【讨论】:

    【解决方案2】:

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

    最初你有这个:

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

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

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

    然后重新分配s:

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

    然后离开方法:

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

    【讨论】:

    • 那么对象呢​​?我以强烈的反菜鸟态度得到了笼统的答案,但还没有得到很好的解释
    • 显示内存结构的好方法。 +1
    • @ Lord.Quackster Java 处理对象的方式与原始类型没有区别。两者都是按值传递的。然而,由于 java 使用对象的“引用”进行操作,因此可以改变传递的引用。但是由于引用本身是按值传递的,所以不能将引用重置为其他值。
    • @TheLQ:我想说 Java 通过变量值的副本传递。在原语的情况下,复制的值是值本身;对于对象,复制的值告诉 JVM 如何在堆内存中检索对象。我不喜欢在谈论这个时使用字符串,因为它们是不可变的(不过,字符串是一个对象)。更多信息:stackoverflow.com/questions/40480/is-java-pass-by-reference/…
    【解决方案3】:
    s =
    

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-30
        • 2016-08-20
        • 2019-05-01
        • 1970-01-01
        • 2019-03-04
        相关资源
        最近更新 更多