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

什么是解释?


当前回答

区别,或可能只是我记得我曾经像原始海报一样的印象是这样的:Java总是通过价值,Java中的所有对象(除了原始对象)都是参考。

其他回答

一个简单的测试,以检查一个语言是否支持通过参考,只是写一个传统的交换。

一个传统的交换方法或函数采取两个论点,并交换它们,以便转换到函数的变量在函数之外发生变化。

(非Java) 基本交换功能结构

swap(Type arg1, Type arg2) {
    Type temp = arg1;
    arg1 = arg2;
    arg2 = temp;
}

如果你能在你的语言中写出这样的方法/函数,那么

Type var1 = ...;
Type var2 = ...;
swap(var1,var2);

事实上,它交换了 var1 和 var2 变量的值,语言支持 pass-by-reference. 但 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.

原始和对象参考,但对象可以改变,如果它们的界面允许。

当您将对象转移到一个方法时,您正在转移一个参考,并且该对象可以通过方法实施进行修改。

void bithday(Person p) {
    p.age++;
}

对象本身的参考,通过值:你可以重新分配参数,但变化不会反映:

void renameToJon(Person p) { 
    p = new Person("Jon"); // this will not work
}

jack = new Person("Jack");
renameToJon(jack);
sysout(jack); // jack is unchanged

作为效应问题,“p”是参考(对象的指标),不能改变。

原始类型通过值,对象的参考也可以被视为原始类型。

为了回报,一切都通过了价值。

主要的角石知识必须是引用的一个,

当对象引用转移到一种方法时,引用本身通过使用呼叫值。 但是,因为引用的值是指对象,则该值的副本仍然是指其相应论点所引用的相同对象。

Java: A Beginner's Guide 第六版 希尔伯特·希尔德

短篇小说:

非原始:Java通过参考值;原始:仅值。

结局。

现在,如果你想想想什么(1)意味着,想象你有一个类的苹果:

class Apple {
    private double weight;
    public Apple(double weight) {
        this.weight = weight;
    }
    // getters and setters ...

}

然后,当你将这个类的一个例子转移到主要方法:

class Main {
    public static void main(String[] args) {
        Apple apple = new Apple(3.14);
        transmogrify(apple);
        System.out.println(apple.getWeight()+ " the goose drank wine...";

    }

    private static void transmogrify(Apple apple) {
        // does something with apple ...
        apple.setWeight(apple.getWeight()+0.55);
    }
}

哦......但你可能知道这一点,你对当你做这样的事情时会发生什么感兴趣:

class Main {
    public static void main(String[] args) {
        Apple apple = new Apple(3.14);
        transmogrify(apple);
        System.out.println("Who ate my: "+apple.getWeight()); // will it still be 3.14? 

    }

    private static void transmogrify(Apple apple) {
        // assign a new apple to the reference passed...
        apple = new Apple(2.71);
    }


}