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,也没有合法的方法来更改它的内容(使用反射是可能的,但是在大多数情况下,使用反射来改变不可变的情况是不好的)

在你的第一个例子中,你做 test = 50,这个东西被称为 autobox,Integer 仍然是不可变的,而 java 在这里所做的,它编译你的代码为 test = new Integer(50)(有一些优化,但让我们暂时跳过它们),因此它将创建值为 50 的整数的新实例,并将方法 updateObject 的变量引用覆盖为该新实例,Integer(20) 仍然存在于内存中的某处,但是方法 updateObject 中的变量测试没有不再参考它。但是,您在方法 main 中有另一个测试变量,该变量仍然引用编号为 20 的 Integer 的第一个实例。

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

希望它会说清楚。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在Java中是按值传递数组还是按引用传递数组?

.bind(this)是按引用还是按值传递?

Ruby是按引用传递还是按值传递?

ELM是按引用传递还是按值传递?

python pandas dataframe,是按值传递还是按引用传递

Kotlin是“按值传递”还是“按引用传递”?

vala是“按引用传递”还是“按值传递”?

在C ++中按值传递还是按常量引用传递更好?

在C#中,我应该按值传递参数并返回相同的变量,还是按引用传递?

困惑,当对象引用被传递时,java是使用按值调用还是按引用调用?

PHP变量是按值还是按引用传递?

我应该按引用还是按值传递大型数组?

Swift函数是按值还是按引用分配/传递?

在Javascript中按值传递和按引用传递

在Android Adapter中按值传递和按引用传递?

如果 VAR_INPUT 是 INTERFACE 类型,那么值是按引用传递还是按值传递?

python递归通过引用还是按值传递?

可移动但不可复制的对象:按值传递还是按引用传递?

JDBC的Connection和Statement对象是按引用传递还是按值传递?

在.NET中,是按值或按引用传递的类对象

C ++中的函数重载按值或按引用传递参数

在python中自定义类对象的参数传递:按引用调用还是按值调用求值?

Java按值传递还是引用传递?有人可以帮助我使用此代码吗?

Array.find是否返回值或引用?我的意思是按值传递还是按引用传递?

Java是按引用还是按值返回

按值传递vs按右值引用传递

我应该按值还是按引用传递函数对象?

复制赋值运算符应该按const引用还是按值传递?

C# 的 Queue.dequeue() 是按引用还是按值传递?