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

什么是解释?


当前回答

在所有的答案中,我们看到Java通过价值,或者正如Gevorg所写的那样:“通过复制变量的价值”,这就是我们应该始终记住的想法。

在Java中,你总是通过复制论点,即你总是在函数中创建一个新的值例子,但有些行为会让你认为你正在通过参考。

此分類上一篇: [ref 1]

void incrementValue(int inFunction){
  inFunction ++;
  System.out.println("In function: " + inFunction);
}

int original = 10;
System.out.print("Original before: " + original);
incrementValue(original);
System.out.println("Original after: " + original);

We see in the console:
 > Original before: 10
 > In Function: 11
 > Original after: 10 (NO CHANGE)

以 [ref 2] 的例子

顯示優雅的機制觀點 max 5 min

(按参考通行) pass-by-copy-of-the-variable-值

void incrementValu(int[] inFuncion){
  inFunction[0]++;
  System.out.println("In Function: " + inFunction[0]);
}

int[] arOriginal = {10, 20, 30};
System.out.println("Original before: " + arOriginal[0]);
incrementValue(arOriginal[]);
System.out.println("Original before: " + arOriginal[0]);

We see in the console:
  >Original before: 10
  >In Function: 11
  >Original before: 11 (CHANGE)

复杂物体本身正在复制,但内部参考正在保持。

此分類上一篇: [ref 3]

package com.pritesh.programs;

class Rectangle {
  int length;
  int width;

  Rectangle(int l, int b) {
    length = l;
    width = b;
  }

  void area(Rectangle r1) {
    int areaOfRectangle = r1.length * r1.width;
    System.out.println("Area of Rectangle : " 
                            + areaOfRectangle);
  }
}

class RectangleDemo {
  public static void main(String args[]) {
    Rectangle r1 = new Rectangle(10, 20);
    r1.area(r1);
  }
}

我想分享的最后一件事是讲座的这个时刻:记忆分配,我认为它非常有用,以了解Java通过值或更为“通过复制变量的值”如Gevorg所写的。

其他回答

Java 通过常见参考,其中通过了参考的副本,这意味着它基本上是值的过渡。 您可以改变参考的内容,如果类是可变的,但您不能改变参考本身. 换句话说,地址不能改变,因为它通过值,但由地址标记的内容可以改变。

我觉得关于“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);
}

此分類上一篇

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

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中,它通过值。

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

此分類上一篇

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

这意味着:

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

讓我試圖用四個例子來解釋我的理解: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]