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

什么是解释?


当前回答

当涉及到对象时,对象本身不能转移到方法,所以我们通过对象的参考(地址)我们可以使用这个参考来操纵原始对象。

Account account1 = new Account();

此分類上一篇

如果我们将 array1 参考变量的值转换为反向Array 方法的论点,则在该方法中创建一个参考变量,而该参考变量则开始指向相同的序列(a)。

public class Test
{
    public static void reverseArray(int[] array1)
    {
        // ...
    }

    public static void main(String[] args)
    {
        int[] array1 = { 1, 10, -7 };
        int[] array2 = { 5, -190, 0 };

        reverseArray(array1);
    }
}

此分類上一篇

所以,如果我们说

array1[0] = 5;

我们有另一个参考变量在逆Array 方法(array2) 指向一个 array c. 如果我们要说

array1 = array2;

如果我们返回参考变量序列2作为逆序列方法的返回值,并将此值归咎于参考变量序列1在主要方法,序列1在主要将开始指向序列c。

public class Test
{
    public static int[] reverseArray(int[] array1)
    {
        int[] array2 = { -7, 0, -1 };

        array1[0] = 5; // array a becomes 5, 10, -7

        array1 = array2; /* array1 of reverseArray starts
          pointing to c instead of a (not shown in image below) */
        return array2;
    }

    public static void main(String[] args)
    {
        int[] array1 = { 1, 10, -7 };
        int[] array2 = { 5, -190, 0 };

        array1 = reverseArray(array1); /* array1 of 
         main starts pointing to c instead of a */
    }
}

此分類上一篇

其他回答

using namespace std;
#include <iostream>

void change (char *&str){   // the '&' makes this a reference parameter
    str = NULL;
}

int main()
{
    char *str = "not Null";
    change(str);
    cout<<"str is " << str;      // ==>str is <null>
}

Java 通过值示例“一个 Java 参考”

public class ValueDemo{
    
    public void change (String str){
        str = null;
    }

     public static void main(String []args){
        ValueDemo vd = new ValueDemo();
        String str = "not null";
        vd.change(str);
        System.out.println("str is " + str);    // ==> str is not null!!
                                                // Note that if "str" was
                                                // passed-by-reference, it
                                                // WOULD BE NULL after the
                                                // call to change().
     }
}

编辑

program passByRefDemo;
type 
   iptr = ^integer;
var
   ptr: iptr;
   
   procedure setToNil(var ptr : iptr);
   begin
       ptr := nil;
   end;

begin
   new(ptr);
   ptr^ := 10;
   setToNil(ptr);
   if (ptr = nil) then
       writeln('ptr seems to be nil');     { ptr should be nil, so this line will run. }
end.

《Java编程语言》(The Java Programming Language)由Ken Arnold、James Gosling(Java的发明者)和David Holmes,第2章,第2节。

Java 编程语言不会通过对象的参考;它通过对象的参考的值. 因为两个副本的相同参考的参考相同的实际对象,通过一个参考变量进行的变化是可见的通过另一个。

这本书的部分有一个很好的解释,参数通过Java和区别通过参考和通过值之间的区别,这是由Java的创作者。

我希望这会解决讨论,但可能不会。

编辑3

通过参考值 - 参考的变化不在呼叫者的范围内反映,但对对象的变化是因为参考是复制的,但原始和复制都指同一个对象。

Java 通过原始类型为值和类型为参考

现在,人们喜欢无限地争论是否“通过参考”是正确的方式来描述Java et al. 实际上做什么。

通过一个对象不会复制对象,转移到函数的对象可以由函数修改其成员,转移到函数的原始值不能由函数修改。

在我的书中,它被称为通过参考。

布莱恩·比(Brian Bi) - 哪种编程语言通过参考?

数据通过参数在函数之间共享,现在有两种方式通过参数:

通过参数 : 呼叫器和呼叫器使用相同的变量为参数. 通过值 : 呼叫器和呼叫器有两个独立的变量与相同的值。

Java 使用 Pass by Value

在传输原始数据时,它复制原始数据类型的值;在传输对象时,它复制对象的地址,并转移到转换方法变量。

Java 在存储变量中遵循以下规则:

原始和对象参考等本地变量在 Stack 记忆中创建,对象在 Heap 记忆中创建。

使用原始数据类型的例子:

public class PassByValuePrimitive {
    public static void main(String[] args) {
        int i=5;
        System.out.println(i);  //prints 5
        change(i);
        System.out.println(i);  //prints 5
    }
    
    
    private static void change(int i) {
        System.out.println(i);  //prints 5
        i=10;
        System.out.println(i); //prints 10
        
    }
}

使用对象的例子:

public class PassByValueObject {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("prem");
        list.add("raj");
        new PassByValueObject().change(list);
        System.out.println(list); // prints [prem, raj, ram]
        
    }
    
    
    private  void change(List list) {
        System.out.println(list.get(0)); // prem
        list.add("ram");
        list=null;
        System.out.println(list.add("bheem")); //gets NullPointerException
    }
}

有这么多长的答案,让我给你一个简单的答案:

Java 总是按值传达一切,也就是说,参考也按值传达。

简而言之,您无法改变任何参数的值,但您可以通过对象参考的方法或属性更改。

经过全面的讨论,我认为现在是时候将所有严重的结果聚集在一起。

/**
 * 
 * @author Sam Ginrich
 * 
 * All Rights Reserved!
 * 
 */
public class JavaIsPassByValue
{

    static class SomeClass
    {
        int someValue;

        public SomeClass(int someValue)
        {
            this.someValue = someValue;
        }
    }

    static void passReferenceByValue(SomeClass someObject)
    {
        if (someObject == null)
        {
            throw new NullPointerException(
                    "This Object Reference was passed by Value,\r\n   that's why you don't get a value from it.");
        }
        someObject.someValue = 49;
    }

    public static void main(String[] args)
    {
        SomeClass someObject = new SomeClass(27);
        System.out.println("Here is the original value: " + someObject.someValue);

        passReferenceByValue(someObject);
        System.out.println(
                "\nAs ´Java is pass by value´,\r\n   everything without exception is passed by value\r\n   and so an object's attribute cannot change: "
                    + someObject.someValue);

        System.out.println();
        passReferenceByValue(null);
    }

) )

从输出中可以很容易地看到,在Java中,一切都通过价值,如此简单!

Here is the original value: 27

As ´Java is pass by value´,
   everything without exception is passed by value
   and so an object´s attribute cannot change: 49

'Exception in thread "main" java.lang.NullPointerException: This Object Reference was passed by value,
   that´s why you don´t get a value from it. 
    at JavaIsPassByValue.passReferenceByValue(JavaIsPassByValue.java:26)
    at JavaIsPassByValue.main(JavaIsPassByValue.java:43)