我一直以为Java使用pass-by-reference. 但是,我读了一篇博客文章,声称Java使用pass-by-value. 我不认为我明白作者所做的区别。

什么是解释?


当前回答

Java 以值传输对象的参考。

其他回答

只需显示对比,请比较以下 C++ 和 Java 剪辑:

在 C++ 中: 注意: 坏代码 - 记忆泄漏! 但它证明了这一点。

void cppMethod(int val, int &ref, Dog obj, Dog &objRef, Dog *objPtr, Dog *&objPtrRef)
{
    val = 7; // Modifies the copy
    ref = 7; // Modifies the original variable
    obj.SetName("obj"); // Modifies the copy of Dog passed
    objRef.SetName("objRef"); // Modifies the original Dog passed
    objPtr->SetName("objPtr"); // Modifies the original Dog pointed to 
                               // by the copy of the pointer passed.
    objPtr = new Dog("newObjPtr");  // Modifies the copy of the pointer, 
                                   // leaving the original object alone.
    objPtrRef->SetName("objRefPtr"); // Modifies the original Dog pointed to 
                                    // by the original pointer passed. 
    objPtrRef = new Dog("newObjPtrRef"); // Modifies the original pointer passed
}

int main()
{
    int a = 0;
    int b = 0;
    Dog d0 = Dog("d0");
    Dog d1 = Dog("d1");
    Dog *d2 = new Dog("d2");
    Dog *d3 = new Dog("d3");
    cppMethod(a, b, d0, d1, d2, d3);
    // a is still set to 0
    // b is now set to 7
    // d0 still have name "d0"
    // d1 now has name "objRef"
    // d2 now has name "objPtr"
    // d3 now has name "newObjPtrRef"
}

在Java,

public static void javaMethod(int val, Dog objPtr)
{
   val = 7; // Modifies the copy
   objPtr.SetName("objPtr") // Modifies the original Dog pointed to 
                            // by the copy of the pointer passed.
   objPtr = new Dog("newObjPtr");  // Modifies the copy of the pointer, 
                                  // leaving the original object alone.
}

public static void main()
{
    int a = 0;
    Dog d0 = new Dog("d0");
    javaMethod(a, d0);
    // a is still set to 0
    // d0 now has name "objPtr"
}

Java 只有兩種通過: 根據內置類型的價值,並根據對象類型的指標的價值。

Java 是值之通(stack memory)

它是如何工作的

首先,让我们明白,在哪里Java存储原始数据类型和对象数据类型。原始数据类型本身和对象参考存储在架子里.对象本身存储在架子里.这意味着,架子记忆存储原始数据类型以及对象的地址。

简单的计划

import java.io.*;
class Aclass
{
    public int a;
}
public class test
{
    public static void foo_obj(Aclass obj)
    {
        obj.a=5;
    }
    public static void foo_int(int a)
    {
        a=3;
    }
    public static void main(String args[])
    {
        //test passing an object
        Aclass ob = new Aclass();
        ob.a=0;
        foo_obj(ob);
        System.out.println(ob.a);//prints 5

        //test passing an integer
        int i=0;
        foo_int(i);
        System.out.println(i);//prints 0
    }
}

从 C/C++ 程序员的观点来看,Java 使用通过值,因此对于原始数据类型(int、char 等)的函数的变化不会反映在呼叫函数中,但是当您通过对象并在函数中更改其数据会员或呼叫会员函数可以改变对象的状态时,呼叫函数会得到变化。

当她在1974年设计CLU时,她进入了相同的术语问题,并发明了“通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用通用。

一个简单的测试,以检查一个语言是否支持通过参考,只是写一个传统的交换。

一个传统的交换方法或函数采取两个论点,并交换它们,以便转换到函数的变量在函数之外发生变化。

(非Java) 基本交换功能结构

swap(Type arg1, Type arg2) {
    Type temp = arg1;
    arg1 = arg2;
    arg2 = temp;
}

如果你能在你的语言中写出这样的方法/函数,那么

Type var1 = ...;
Type var2 = ...;
swap(var1,var2);

事实上,它交换了 var1 和 var2 变量的值,语言支持 pass-by-reference. 但 Java 不允许这样的东西,因为它支持只通过值,而不是指标或参考。