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

什么是解释?


当前回答

将变量转换为方法(目标 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

其他回答

假设,常见的语言是错误的,基于不准确的语言

编程语言的作者没有权力重新命名已建立的编程概念。

原始 Java 类型 byte, char, short, int, long float, double 肯定是通过值。

所有其他类型都是对象:对象成员和参数技术上是参考。

因此,这些“参考”是通过的“值”,但没有对象建设发生在架子上. 任何对象成员的变化(或对象在序列的情况下)适用于相同的原始对象;这种参考正是符合一个例子的指标的逻辑转移到某个函数在任何C直径,在那里我们使用称之为通过一个对象的参考。

特別我們有這件事 java.lang.NullPointer 例外,這在純粹的過值概念中毫無意義。

“pass-by-value”和“pass-by-reference”是指变量;“pass-by-value”是指变量的值转移到函数/方法;“pass-by-reference”是指该变量的参考转移到函数;“pass-by-reference”是指变量的值转移到函数;“pass-by-reference”是指变量的值转移到函数。

它如同这样:

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
}

同样:

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

    foo(aDog);
    // when foo(...) returns, the name of the dog has been changed to "Fifi"
    aDog.getName().equals("Fifi"); // true
    // but it is still the same dog:
    aDog == oldDog; // true
}

public static void foo(Dog d) {
    d.getName().equals("Max"); // true
    // this changes the name of d to be "Fifi"
    d.setName("Fifi");
}

有关参考通行和值通行的更多信息,请参见以下答案: https://stackoverflow.com/a/430958/6005228. 这更详细地解释了两者背后的语法和历史,并解释了为什么Java和许多其他现代语言似乎在某些情况下都会做两件事。

我在这里创建了一个专门为任何编程语言提出这些问题的条纹。

Java 也被提及,这里是简短的概述:

Java 通过它的参数值“值”是Java 唯一的方式将一个参数转换为一个方法,使用从所提供的对象作为参数的方法将改变对象,因为参考指向原始对象(如果该方法本身改变某些值)。

斯科特·斯坦奇菲尔德先生写了一个很好的答案. 这里是你要确认的课堂,他是什么意思:

public class Dog {

    String dog ;
    static int x_static;
    int y_not_static;

    public String getName()
    {
        return this.dog;
    }

    public Dog(String dog)
    {
        this.dog = dog;
    }

    public void setName(String name)
    {
        this.dog = name;
    }

    public static void foo(Dog someDog)
    {
        x_static = 1;
        // y_not_static = 2;  // not possible !!
        someDog.setName("Max");     // AAA
        someDog = new Dog("Fifi");  // BBB
        someDog.setName("Rowlf");   // CCC
    }

    public static void main(String args[])
    {
        Dog myDog = new Dog("Rover");
        foo(myDog);
        System.out.println(myDog.getName());
    }
}

因此,我们从主()一个名叫Rover的狗,然后我们将一个新的地址给我们通过的指标,但最终,狗的名字不是Rover,也不是Fifi,也许不是Rowlf,但Max。

事實的結論是,在「通過通過」的表達中,意思是完全不同於Java的常見意思。

但技术术语通过参考/值从编程语言理论是谈论一个参考到记忆细胞持有变量,这是一个完全不同的东西。