理解Java被传递的价​​值概念?

时间:2015-03-09 03:16:41

标签: java

Java中最受欢迎的问题之一最受欢迎的答案之一是:

  

Java始终是按值传递的。难以理解的是Java将对象作为引用传递,并且这些引用按值传递。

那么" Java将对象作为引用传递,那些引用是按值传递的。"意思?

这是否意味着:

将原始变量指向的内存位置复制为新临时变量的值? (如果是这种情况,函数内部所做的所有更改都将反映在原文中,对吗?)

如果没有,这是什么意思?

4 个答案:

答案 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 (对象本身无法修改,必须为所有修改创建一个新对象。

如果它是可变的,如StringBuilderHashMap<String, String>,则该函数能够修改它,并且函数调用返回后函数内的更改仍然存在。但是,请注意,更改引用类型所指向的是而不是修改它,在这种情况下,您只是更改引用类型指向的内容,而不是参数引用的原始对象,而是执行像strbuilder.append("xyz")这样的操作是。

如果它是不可变的,如StringInteger那么函数中的所有修改都将创建一个新对象,并且在函数调用返回后,更改将不会到位。

答案 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);

xy不会改变。

参考文献也是如此:

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.
}