1

我对一件微不足道的事情感到困惑 - 将参数传递给方法并更改它们的值......我最好给你一些代码:

public class Test {
  public static void main(String[] args) {
    Integer val = new Integer(41);
    upd(val);
    System.out.println(val);

    Man man = new Man();
    updMan(man);
    System.out.println(man.name);
  }

  static void upd(Integer val) {
    val = new Integer(42);
  }

  static void updMan(Man man) {
    man.name = "Name";
  }

  static class Man {
    String name;
  }
}

你能解释一下为什么我传递的 Integer 对象没有更新,而 Man 对象是?Integer 和 Man 对象不是通过引用传递(由于它们的非原始性质)吗?

4

4 回答 4

1

因为Integer您正在创建一个新对象。对于Man您只需更改其值之一,对象man将保持不变。

考虑以下:

static void updMan(Man man) {
  man = new Man();
  man.name = "Another Man";
}

这也不会改变您的初始man.

- 编辑

您可以通过以下方式“模拟” 的可变性Integer

static void upd(Integer val) {
    try {
        Field declaredField = val.getClass().getDeclaredField("value");
        declaredField.setAccessible(true);
        declaredField.set(val, 42);
    } catch (Exception e) {
    }
}
于 2012-06-08T09:49:43.613 回答
1

它被称为按值传递。当您将某个对象传递给圆顶方法时,Java 会创建对该对象的引用副本。如果您在进入方法主体后立即检查对象的哈希码,它将与传递对象的哈希码相同。但是当您在方法内部更改它时,对象会更改并且引用不再指向同一个对象。

编辑:代码示例

public class TestPass {

    public static void main(String[] args) {
        String ss= "sample";
        System.out.println("Outside method: "+ss.hashCode());
        method(ss);

    }

    static void method(String s){
        System.out.println("Inside method: "+s.hashCode());
        s+='!';
        System.out.println("Inside method after object change: "+s.hashCode());
    }

}

输出:

Outside method: -909675094
Inside method: -909675094
Inside method after change: 1864843191
于 2012-06-08T09:57:00.027 回答
1

Java中作为参数的对象通过引用副本作为参数传输-因此,如果您通过引用副本更改对象-您将更新对象。

在您的upd(Integer val)方法的情况下,您创建一个新Integer对象,以便引用副本现在指向一个新对象,而不是旧对象。因此更改该对象不会影响原始对象。

于 2012-06-08T10:03:13.233 回答
0
man.name = "Name"; 

您实际上是在此处更改同一对象中的某些内容,而不是像在 Integer 中那样创建新对象。

于 2012-06-08T09:51:33.050 回答