我一直以为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 以值传输对象的参考。

using namespace std;
#include <iostream>

void change (char *&str){   // the '&' makes this a reference parameter
    str = NULL;
}

int main()
{
    char *str = "not Null";
    change(str);
    cout<<"str is " << str;      // ==>str is <null>
}

Java 通过值示例“一个 Java 参考”

public class ValueDemo{
    
    public void change (String str){
        str = null;
    }

     public static void main(String []args){
        ValueDemo vd = new ValueDemo();
        String str = "not null";
        vd.change(str);
        System.out.println("str is " + str);    // ==> str is not null!!
                                                // Note that if "str" was
                                                // passed-by-reference, it
                                                // WOULD BE NULL after the
                                                // call to change().
     }
}

编辑

program passByRefDemo;
type 
   iptr = ^integer;
var
   ptr: iptr;
   
   procedure setToNil(var ptr : iptr);
   begin
       ptr := nil;
   end;

begin
   new(ptr);
   ptr^ := 10;
   setToNil(ptr);
   if (ptr = nil) then
       writeln('ptr seems to be nil');     { ptr should be nil, so this line will run. }
end.

《Java编程语言》(The Java Programming Language)由Ken Arnold、James Gosling(Java的发明者)和David Holmes,第2章,第2节。

Java 编程语言不会通过对象的参考;它通过对象的参考的值. 因为两个副本的相同参考的参考相同的实际对象,通过一个参考变量进行的变化是可见的通过另一个。

这本书的部分有一个很好的解释,参数通过Java和区别通过参考和通过值之间的区别,这是由Java的创作者。

我希望这会解决讨论,但可能不会。

编辑3

通过参考值 - 参考的变化不在呼叫者的范围内反映,但对对象的变化是因为参考是复制的,但原始和复制都指同一个对象。

基本上,重新定义对象参数不会影响论点,例如,

private static void foo(Object bar) {
    bar = null;
}

public static void main(String[] args) {
    String baz = "Hah!";
    foo(baz);
    System.out.println(baz);
}

这个工作的原因是因为字符串是 baz 的值的副本,这只是“Hah!”的参考。如果它是实际的参考本身,那么 foo 会重新定义 baz 到 null。

讓我試圖用四個例子來解釋我的理解:Java是通過價值,而不是通過参考。

* * *

public class PassByValueString {
    public static void main(String[] args) {
        new PassByValueString().caller();
    }

    public void caller() {
        String value = "Nikhil";
        boolean valueflag = false;
        String output = method(value, valueflag);
        /*
         * 'output' is insignificant in this example. we are more interested in
         * 'value' and 'valueflag'
         */
        System.out.println("output : " + output);
        System.out.println("value : " + value);
        System.out.println("valueflag : " + valueflag);

    }

    public String method(String value, boolean valueflag) {
        value = "Anand";
        valueflag = true;
        return "output";
    }
}

output : output
value : Nikhil
valueflag : false

例子2:

/** * * Pass By 價值 */

public class PassByValueNewString {
    public static void main(String[] args) {
        new PassByValueNewString().caller();
    }

    public void caller() {
        String value = new String("Nikhil");
        boolean valueflag = false;
        String output = method(value, valueflag);
        /*
         * 'output' is insignificant in this example. we are more interested in
         * 'value' and 'valueflag'
         */
        System.out.println("output : " + output);
        System.out.println("value : " + value);
        System.out.println("valueflag : " + valueflag);

    }

    public String method(String value, boolean valueflag) {
        value = "Anand";
        valueflag = true;
        return "output";
    }
}

output : output
value : Nikhil
valueflag : false

/** 这个“通过价值”具有“通过参考”的感觉

但是,从这个例子,我们可以理解,它只是通过值,记住,在这里我们通过参考作为值. 也就是说:参考通过值. 这就是为什么它们可以改变,但它仍然保持在当地范围后真实。

public class PassByValueObjectCase1 {

    private class Student {
        int id;
        String name;
        public Student() {
        }
        public Student(int id, String name) {
            super();
            this.id = id;
            this.name = name;
        }
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        @Override
        public String toString() {
            return "Student [id=" + id + ", name=" + name + "]";
        }
    }

    public static void main(String[] args) {
        new PassByValueObjectCase1().caller();
    }

    public void caller() {
        Student student = new Student(10, "Nikhil");
        String output = method(student);
        /*
         * 'output' is insignificant in this example. we are more interested in
         * 'student'
         */
        System.out.println("output : " + output);
        System.out.println("student : " + student);
    }

    public String method(Student student) {
        student.setName("Anand");
        return "output";
    }
}

结果

output : output
student : Student [id=10, name=Anand]

例子4:

* * *

除了在Example3(PassByValueObjectCase1.java)中提到的外,我们不能在原始范围之外更改实际参考。

注意: 我不符合私人课堂学生的代码. 学生的课堂定义与例子3相同。

public class PassByValueObjectCase2 {

    public static void main(String[] args) {
        new PassByValueObjectCase2().caller();
    }

    public void caller() {
        // student has the actual reference to a Student object created
        // can we change this actual reference outside the local scope? Let's see
        Student student = new Student(10, "Nikhil");
        String output = method(student);
        /*
         * 'output' is insignificant in this example. we are more interested in
         * 'student'
         */
        System.out.println("output : " + output);
        System.out.println("student : " + student); // Will it print Nikhil or Anand?
    }

    public String method(Student student) {
        student = new Student(20, "Anand");
        return "output";
    }

}

output : output
student : Student [id=10, name=Nikhil]

Java 通过值的参数,并且仅值。

短篇小说 短篇小说:

对于来自C#的人来说:没有“外”参数,对于来自PASCAL的人来说:没有“存在”参数。

这意味着你不能从对象本身改变参考,但你总是可以改变对象的属性。

一个工作室是使用 StringBuilder 参数而不是 String。