"pass by value"还是"pass by reference" Java ?



我想了解参数是如何在Java中传递的。例如,我有以下代码:

class Runner{
public static void main(String[] args)
{
Integer test = new Integer(20);
updateObject(test);
System.out.println(test);
}
public static void updateObject(Integer test)
{
test = 50;
}
}

打印"20">

但是,如果我像这样使用我自己的类来代替Integer:

import java.util.*;
class Test {
int num;
Test(int x){
num = x;
}
Test(){
num = 0;
}
}
class Runner{
public static void main(String[] args)
{
Test test = new Test(20);
updateObject(test);
System.out.println(test.num);
}
public static void updateObject(Test test)
{
test.num = 50;
}
}

在本例中println打印&;50&;

为什么在第一种情况下我的参数没有改变,但在第二种情况下它已经改变了?

在java中,它总是按值传递参数。棘手的是,如果你处理类的实例,它是引用类型,当你作为参数传递给方法时,对实例的引用按值传递,这意味着对该对象的引用将被复制到方法参数,所以引用充当值本身。

在你的第一个例子中,当你执行Integer test = new Integer()时,你创建了一个新的Integer实例,并将它的引用设置为测试变量。这里的棘手部分是,Integer是不可变类型,即使你有Integer的引用,也没有合法的方法来改变它的内容(反射是可能的,但是在大多数情况下使用反射来改变不可变是不好的)

接下来在你的第一个例子中,你做test = 50,这个东西叫做autobox, Integer仍然是不可变的,java在这里做的是,它将你的代码编译为test = new Integer(50)(这里有一些优化,但我们现在跳过它们),所以它会创建一个值为50的Integer的新实例,并将updateObject方法的变量引用覆盖到那个新实例,Integer(20)仍然存在于内存的某个地方,然而,updateObject方法中的变量test不再引用它了。但是,在方法main中有另一个测试变量,并且该变量仍然保持对编号为20的Integer的第一个实例的引用。

关于第二个示例,现在创建了可变类型,并执行line: test。Num = 50 -它将保持对类实例的引用不变,但它将改变类的字段。在第二个例子中,测试两个静态方法中引用同一实例的变量。这就是为什么它输出相同的值

希望它能说清楚。

最新更新