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

什么是解释?


当前回答

Java 是值之通(stack memory)

它是如何工作的

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

其他回答

我做了这个小图表,显示了数据是如何创建和通过的

此分類上一篇

注意:原始值作为值传递,该值的第一个参考是方法的论点。

这意味着:

您可以在函数内更改 myObject 的值 但您不能更改 myObject 引用到,函数内,因为点不是 myObject 记住,点和 myObject 是引用,不同引用,但是,这些引用在同一个新点(0,0)

在Java中,方法论都是通过价值的:

Java 论点都是通过值(当使用方法时,值或参考复制):

在原始类型的情况下,Java行为是简单的:值复制到原始类型的另一个例子。

行为可能与原始类型不同:因为复制的对象变量包含相同的地址(到相同的对象)。对象的内容/会员可能仍然在一个方法内进行修改,然后在外部访问,给出幻觉(包含)对象本身通过参考。

“紧张”对象似乎是城市传说说“对象通过参考”的好对例子:

A String Object,持有字符的序列宣布最终不能修改. 只有对象的地址可以用另一个使用“新”。 使用“新”更新变量,不会让对象从外部访问,因为变量最初通过值并复制。

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

/**
 * 
 * @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)

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

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

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

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

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

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

将变量转换为方法(目标 7.3) 7.3 确定对对象参考和原始值的影响,当它们转换为对参数进行任务或其他修改操作的方法时。

1. import java.awt.Dimension;
2. class ReferenceTest {
3.     public static void main (String [] args) {
4.         Dimension d = new Dimension(5,10);
5.         ReferenceTest rt = new ReferenceTest();
6.         System.out.println("Before modify() d.height = " + d.height);
7.         rt.modify(d);
8.         System.out.println("After modify() d.height = "
9.     }
10.
11.
12.
13.   }
14. }

C:\Java Projects\Reference>java ReferenceTest
Before modify() d.height = 10
dim = 11
After modify() d.height = 11

注意,当第 4 行的尺寸对象转移到修改() 方法时,在该方法中发生的对象的任何变化都会转移到该对象的参考转移。在前面的例子中,参考变量 d 和 dim 都指向相同的对象。

        void bar() {
           Foo f = new Foo();
           doStuff(f);
        }
        void doStuff(Foo g) {
           g.setName("Boo");
           g = new Foo();
        }

class ReferenceTest {
    public static void main (String [] args) {
      int a = 1;
      ReferenceTest rt = new ReferenceTest();
      System.out.println("Before modify() a = " + a);
      rt.modify(a);
      System.out.println("After modify() a = " + a);
    }
    void modify(int number) {
      number = number + 1;
      System.out.println("number = " + number);
    }
}

  Before modify() a = 1
  number = 2
  After modify() a = 1