我对一件琐碎的事情感到困惑 - 将参数传递给方法并更改其值...我最好给你一些代码:
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对象(由于它们的非原始性质)?
答案 0 :(得分: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) {
}
}
答案 1 :(得分:1)
它被称为按值传递。当您将一些对象传递给dome方法时,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
答案 2 :(得分:1)
作为Java中的参数的对象通过引用副本作为参数传输 - 因此,如果您通过引用副本更改对象 - 您将更新对象。
如果您使用upd(Integer val)
方法,则会创建一个新的Integer
对象,以便引用副本现在指向一个新对象,而不是旧对象。因此,更改该对象不会影响原始对象。
答案 3 :(得分:0)
man.name = "Name";
实际上,您正在更改同一对象中的某些内容而不是像在整数情况下那样创建新对象。