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

什么是解释?


当前回答

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

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
}

其他回答

正如许多人之前提到的那样,Java总是有价值的。

下面是另一个例子,这将帮助你理解差异(经典交换例子):

public class Test {
  public static void main(String[] args) {
    Integer a = new Integer(2);
    Integer b = new Integer(3);
    System.out.println("Before: a = " + a + ", b = " + b);
    swap(a,b);
    System.out.println("After: a = " + a + ", b = " + b);
  }

  public static swap(Integer iA, Integer iB) {
    Integer tmp = iA;
    iA = iB;
    iB = tmp;
  }
}

印刷:

前: a = 2, b = 3 后: a = 2, b = 3

这是因为 iA 和 iB 是新的本地参考变量,具有相同值的过去参考(他们的点到 a 和 b 相应)。因此,试图改变 iA 或 iB 的参考将仅在本地范围内变化,而不是在该方法之外。

Java 总是使用 Call by Value. 这意味着该方法获得所有参数值的副本。

考虑下列三种情况:

1、试图改变原始变量

public static void increment(int x) { x++; }

int a = 3;
increment(a);

x 将复制一个值,并将增加 x,一个将保持相同的值

(二)试图改变对象的原始领域

public static void increment(Person p) { p.age++; }

Person pers = new Person(20); // age = 20
increment(pers);

p 将复制个体的参考值,并将增加年龄领域,变量是指相同的对象,所以年龄改变。

(三)试图改变参考变量的参考值

public static void swap(Person p1, Person p2) {
    Person temp = p1;
    p1 = p2;
    p2 = temp;
}

Person pers1 = new Person(10);
Person pers2 = new Person(20);
swap(pers1, pers2);

呼叫交换 p1 后,p2 复制 pers1 和 pers2 的参考值与值交换,因此 pers1 和 pers2 仍然相同。

因此,您只能在将参考值复制到该对象时更改对象的字段。

我遇到了类似的问题. 这个关于圈子的故事对我来说是一个具体的答案. 我想添加到答案. 希望它能帮助那些有类似问题的人。

https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html

在方法中,循环起初指 myCircle. 该方法改变了对象的 x 和 y 坐标,循环参考(即 myCircle)为 23 和 56, 相应. 这些变化将持续,当方法返回. 然后循环被分配一个参考一个新的循环对象与 x = y = 0. 这个重新分配没有永久性, 但是,因为参考通过了值

Book book = new Book("Effective Java");

在上面的例子中,参考变量是“书”存储在堆积中。 由新运营商创建的例子 ->新书(“有效Java”)存储在Heap中. ref变量“书”有在Heap中分配的对象地址。

此分類上一篇

public class PrimitiveTypeExample { 
    public static void main(string[] args) {
       int num = 10;
       System.out.println("Value before calling method: " + num);
       printNum(num);
       System.out.println("Value after calling method: " + num);
    }
    public static void printNum(int num){
       num = num + 10;
       System.out.println("Value inside printNum method: " + num);
    }
}

考虑,例如通过一个定义阶级的对象作为论点的例子。

此分類上一篇

此分類上一篇

因此,当任何东西作为方法论时,它总是是Stack实体 - 无论是原始还是参考变量. 我们永远不会通过在Heap中存储的东西. 因此,在Java,我们总是通过值在Stack中,它通过值。

我觉得关于“pass-by-reference vs pass-by-value”的争论并不太有用。

在我们到达Java实施之前,滑板/滑板上走路:价值观以顺序的方式滑板上走路,就像一家咖啡馆里的滑板一样。 滑板中的记忆(也称为动态记忆)是危险的,不组织的。

好吧! 首先,地方原始人走在地板上,所以这个代码:

int x = 3;
float y = 101.1f;
boolean amIAwesome = true;

此分類上一篇

当你宣布和即时一个对象时,实际对象会走在地板上,什么会走在地板上?对象的地址会走在地板上,C++程序员会称之为指标,但一些Java开发人员反对“指标”这个词。

像这样:

int problems = 99;
String name = "Jay-Z";

此分類上一篇

JButton[] marxBros = new JButton[3];
marxBros[0] = new JButton("Groucho");
marxBros[1] = new JButton("Zeppo");
marxBros[2] = new JButton("Harpo");

此分類上一篇

private static void shout(String name){
    System.out.println("There goes " + name + "!");
}

public static void main(String[] args){
    String hisName = "John J. Jingleheimerschmitz";
    String myName = hisName;
    shout(myName);
}

此分類上一篇

所以,值,参考?你说“土豆”。