我有一个问题。我有下一个代码示例:
class Test{
static void change(String s){
s = "newString";
}
public static void main(String args[]){
String s = "String";
change(s);
System.out.print(s);
}
}
我看到结果是“String”。 现在我有以下代码:
class A{
int a;
static void change(A a){
a.a = 10;
}
public static void main(String[] args){
A a = new A();
a.a = 5;
change(a);
System.out.print(a.a);
}
}
这最终得到的值10.我不明白为什么?这两个都不是参考?为什么不是第一个代码输出:“newString”?
答案 0 :(得分:4)
这里的区别在于第一个例子:
static void change(String s){
s = "newString";
}
您重新分配局部变量s
以指向新的String
。这对String
之前指向的s
没有影响,并且在方法change()
之外没有任何影响。
在第二种情况下
static void change(A a){
a.a = 10;
}
您正在修改引用A
指向的a
实例,因此当您从方法返回时,此更改仍然存在。
答案 1 :(得分:0)
Java按值传递对象引用,因此您无法重新生成作为参数传递的对象。这就是您在第一个示例中看到的内容。
然而,您当然可以修改传递的对象的内容。这是你在第二个例子中看到的。
答案 2 :(得分:0)
在String的情况下,引用s
是本地副本,因此更改它不会做任何事情。
在int
个案例中,您使用的是对包含另一个字段的A
的引用。当您更改该字段时,您不会更改副本。
等效的方法是在方法中执行a = new A();
之类的操作,这也不会改变原文。
答案 3 :(得分:0)
在第一种情况下,方法change(String s)
正在修改原始引用的副本。
在第二种情况下,方法change(A a)
正在修改引用指向的变量,它不相同。方法中使用的引用a
是一个副本,但不是它指向的变量a.a
。
答案 4 :(得分:0)
因此,在s
中获得change
的第一种情况下,您没有获得实际参考,但是您获得了参考副本,因此指定新值不会影响旧版本值。
在第二种情况下,您传递的是A
的实例,在这种情况下,您将获得引用a
的副本,但您可以处理该实例中的实际值。作为a
的{{1}},当您更改a
的值时,它会影响实际值。
要澄清更多,在第二种情况下,如果你这样做
int a
它不会更改您传递的原始change(A a){
a = new A();
a.a = 100;
}
以更改a
答案 5 :(得分:0)
Java是按值传递而不是按引用传递。这意味着在方法
中void changeVer1(Something val){
val = new Something("else");
}
val
是changeVer1
方法的 local 变量,它是您用作方法参数的引用的副本。这意味着当你做
val = new Something("Else");
您正在更改此本地副本的值,因此这不会更改您用作此方法参数的“原始”引用的值。
现在让我们来看看这个方法的其他版本
void changeVer2(Something val){
val.someField = 42;
}
由于val
是您传递的引用副本,因此它将保留与原始引用相同的对象,并且此对象的状态的每次更改都将通过原始引用显示。