Java中最受欢迎的问题之一最受欢迎的答案之一是:
Java始终是按值传递的。难以理解的是Java将对象作为引用传递,并且这些引用按值传递。
那么" Java将对象作为引用传递,那些引用是按值传递的。"意思?
这是否意味着:
将原始变量指向的内存位置复制为新临时变量的值? (如果是这种情况,函数内部所做的所有更改都将反映在原文中,对吗?)
如果没有,这是什么意思?
答案 0 :(得分:2)
将对象引用视为“指向值的指针”
将值传递给方法时,将指针传入,因此两个指针(方法中的指针和传入的指针)指向同一个指针。
考虑一下
public static void main(String[] args){
Foo cl = new Foo();
cl.z= 100;
method(cl);
System.out.println(cl.z);
}
private static void method(Foo bar){
bar.z=10;
}
在致电method
之前,cl.z将为100,但在您将其传入之后,它将等于10。
这是不正确的:
public static void main(String[] args){
Foo cl = new Foo();
cl.z= 100;
method(cl);
System.out.println(cl.z);
}
private static void method(Foo bar){
bar = new Foo();
bar.z=10000;
}
这不会打印10000,因为您无法指定pointer
来引用不同的对象
答案 1 :(得分:0)
是的,Java总是按值传递,包括引用类型和基本类型。但这并不意味着函数内的变化总是会影响作为参数传入的对象。
如果传入基本类型,则没有传递引用,它是纯值,并且调用范围中的任何值都不会改变。
如果传入引用类型,函数是否可以修改它取决于类型是 mutable (可以修改对象)还是 immutable (对象本身无法修改,必须为所有修改创建一个新对象。
如果它是可变的,如StringBuilder
或HashMap<String, String>
,则该函数能够修改它,并且函数调用返回后函数内的更改仍然存在。但是,请注意,更改引用类型所指向的是而不是修改它,在这种情况下,您只是更改引用类型指向的内容,而不是参数引用的原始对象,而是执行像strbuilder.append("xyz")
这样的操作是。
如果它是不可变的,如String
或Integer
那么函数中的所有修改都将创建一个新对象,并且在函数调用返回后,更改将不会到位。
答案 2 :(得分:0)
当我们说Java是按值传递时,这意味着如果修改方法内的参数,它对调用者没有影响。例如:
public void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
}
这一切都是交换参数的本地副本。因此,如果你说
int x = something;
int y = somethingElse;
swap(x, y);
x
和y
不会改变。
参考文献也是如此:
public void someOperation(MyClass a) {
a = ...something...;
}
在您的方法中,a
是您传入的任何引用的副本;如果您将a
重新分配给方法中的其他内容,则不会影响调用方中的任何变量。
MyClass x = ...;
someOperation(x);
即使您已更改方法中的参数x
, a
也不会更改。
请注意,这意味着x
本身不会改变。它不会指向不同的MyClass
实例,即使方法中的a
已更改为引用不同的MyClass
实例。但是,即使引用未更改,引用所引用的对象也可以通过方法进行更改。
答案 3 :(得分:0)
这意味着引用(指向对象的内存指针)按值传递。如果修改对象,则修改对象的引用;因此,您的应用程序将会看到更改。如果您修改了指针,那么您只需将其更改为方法范围。
void method(Foo f) {
f.bar = 10; // Seen accross your application.
f = new Foo(); // Modifying your pointer. This does not change the previous object.
}