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

什么是解释?


当前回答

Java 严格要求 pass-by-value. 通过使用 pass-by-values 的参数不会影响/改变原始变量. 在下一个程序中,我们启动了一种称为 'x' 的变量,并使用 pass-by-value 技术来证明变量的值如何保持不变。

public class Main 
{    
   public static void main(String[] args)
   { 
       //Original value of 'x' will remain unchanged 
       // in case of call-by-value 
   
       int x = 5;
       System.out.println( "Value of x before call-by-value: " + x);
       // 5

       processData(x);
       System.out.println("Value of x after call-by-value: " + x);
       // 5
   }
   public static void processData(int x) 
   { 
       x=x+10;          
   }
}

通过值和通过参考值之间的差异

什么是 Pass by Value?

通过值,函数参数的值将复制到记忆中的另一个位置,在函数内访问或修改变量时,它只会访问复制。

通过参考,记忆地址转移到该函数,换句话说,函数可以访问实际变量。

定义

Pass by value 是指将函数参数值复制到另一个变量的机制,而 pass by reference 是指将实际参数转移到函数的机制。

变化

目前的参数

其他回答

我们有2个不同的术语(Call-by-Value/Call-by-Reference)但至少有3(!)不同的方式处理上述数据,当将其转移到一个方法:

我们的数据是复制的,复制加到一个方法. 复制的变化不会在外面传播.(想想一个 int 在 Java 或 C++ 或 C#.) 一个指标(记忆地址)我们的数据加到方法而不是. 我们的数据的变化加到外面传播. 我们也可以指向一些新的例子,让我们的原始数据危害。

在 OO 世界中, #1 是 Call-by-Value 和 #2 是 Call-by-Reference. 但是,由于我们只有两个条件为三个选项,没有两个条件之间的明确定义,由于选项 #3 。

“为什么Java开发人员会坚持自己的术语?”

“有没有解决这个混乱的办法?”

最终,不管我们称之为什么,因为只要我们彼此理解,没有混乱。

Java 编程语言仅通过值的论点,也就是说,您无法从所称方法中更改呼叫方法中的论点值。


但是,当一个对象例子作为论点转移到一种方法时,论点的价值不是对象本身,而是对象的参考。


对于许多人来说,这似乎是通过参考,行为上,它与通过参考有很多共同点,但是,有两个原因,这是不准确的。

第一,改变已转化为一种方法的能力仅适用于对象,而不是原始价值;第二,与对象类型变量相关的实际价值是对象的参考,而不是对象本身。


The following code example illustrates this point:
1 public class PassTest {
2
3   // Methods to change the current values
4   public static void changeInt(int value) {
5     value = 55;
6  }
7   public static void changeObjectRef(MyDate ref) {
8     ref = new MyDate(1, 1, 2000);
9  }
10   public static void changeObjectAttr(MyDate ref) {
11     ref.setDay(4);
12   }
13
14 public static void main(String args[]) {
15     MyDate date;
16     int val;
17
18     // Assign the int
19     val = 11;
20     // Try to change it
21     changeInt(val);
22     // What is the current value?
23     System.out.println("Int value is: " + val);
24
25 // Assign the date
26     date = new MyDate(22, 7, 1964);
27     // Try to change it
28     changeObjectRef(date);
29     // What is the current value?
30 System.out.println("MyDate: " + date);
31
32 // Now change the day attribute
33     // through the object reference
34     changeObjectAttr(date);
35     // What is the current value?
36 System.out.println("MyDate: " + date);
37   }
38 }

This code outputs the following:
java PassTest
Int value is: 11
MyDate: 22-7-1964
MyDate: 4-7-1964
The MyDate object is not changed by the changeObjectRef method;
however, the changeObjectAttr method changes the day attribute of the
MyDate object.

我会以另一种方式说:

在 Java 引用中,这些引用是通过的(但不是对象),这些引用是通过的值(引用本身是复制的,你有 2 引用作为结果,你没有控制在方法中的第 1 引用下)。

例如,在Python相同的情况,但有文章,描述他们称之为Pass-by-reference,只有原因引用被使用。

理解它在两个步骤:

您无法更改对象本身的参考,但您可以使用此已过的参数作为对象的参考。

如果您想要更改参考背后的值,您只会在同一名称“d”的字符串上宣布一个新的变量。

public static void foo(Dog d) {
  d.Name = "belly";
  System.out.println(d); //Reference: Dog@1540e19d

  d = new Dog("wuffwuff");
  System.out.println(d); //Dog@677327b6
}
public static void main(String[] args) throws Exception{
  Dog lisa = new Dog("Lisa");
  foo(lisa);
  System.out.println(lisa.Name); //belly
}

对于简单性和言语性 其通过值参考:

public static void main(String[] args) {
    Dog aDog = new Dog("Max");
    Dog oldDog = aDog;

    // we pass the object to foo
    foo(aDog);
    // aDog variable is still pointing to the "Max" dog when foo(...) returns
    aDog.getName().equals("Max"); // true
    aDog.getName().equals("Fifi"); // false
    aDog == oldDog; // true
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true
    // change d inside of foo() to point to a new Dog instance "Fifi"
    d = new Dog("Fifi");
    d.getName().equals("Fifi"); // true
}