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

什么是解释?


当前回答

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

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

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

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

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

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

其他回答

Java 是值之通(stack memory)

它是如何工作的

首先,让我们明白,在哪里Java存储原始数据类型和对象数据类型。原始数据类型本身和对象参考存储在架子里.对象本身存储在架子里.这意味着,架子记忆存储原始数据类型以及对象的地址。

public void foo(Object param)
{
  // some code in foo...
}

public void bar()
{
  Object obj = new Object();

  foo(obj);
}

它是相同的......

public void bar()
{
  Object obj = new Object();

  Object param = obj;

  // some code in foo...
}

不要考虑在这个讨论中不相关的站点。

你会遇到的最常见的运营商之一是简单的任务运营商“="......它将其右上的值归分为其左上的运营商: int cadence = 0; int speed = 0; int gear = 1; 这个运营商也可以用于对象归分对象参考。

很明显,这个运营商如何以两种不同的方式行动:分配值和分配参考;最后,当它是一个对象......第一,当它不是一个对象,即当它是一个原始的。

真相在代码中,让我们尝试一下:

public class AssignmentEvaluation
{
  static public class MyInteger
  {
    public int value = 0;
  }

  static public void main(String[] args)
  {
    System.out.println("Assignment operator evaluation using two MyInteger objects named height and width\n");

    MyInteger height = new MyInteger();
    MyInteger width  = new MyInteger();

    System.out.println("[1] Assign distinct integers to height and width values");

    height.value = 9;
    width.value  = 1;

    System.out.println("->  height is " + height.value + " and width is " + width.value + ", we are different things! \n");

    System.out.println("[2] Assign to height's value the width's value");

    height.value = width.value;

    System.out.println("->  height is " + height.value + " and width is " + width.value + ", are we the same thing now? \n");

    System.out.println("[3] Assign to height's value an integer other than width's value");

    height.value = 9;

    System.out.println("->  height is " + height.value + " and width is " + width.value + ", we are different things yet! \n");

    System.out.println("[4] Assign to height the width object");

    height = width;

    System.out.println("->  height is " + height.value + " and width is " + width.value + ", are we the same thing now? \n");

    System.out.println("[5] Assign to height's value an integer other than width's value");

    height.value = 9;

    System.out.println("->  height is " + height.value + " and width is " + width.value + ", we are the same thing now! \n");

    System.out.println("[6] Assign to height a new MyInteger and an integer other than width's value");

    height = new MyInteger();
    height.value = 1;

    System.out.println("->  height is " + height.value + " and width is " + width.value + ", we are different things again! \n");
  }
}

这就是我跑步的结果:

Assignment operator evaluation using two MyInteger objects named height and width

[1] Assign distinct integers to height and width values
->  height is 9 and width is 1, we are different things! 

[2] Assign to height's value the width's value
->  height is 1 and width is 1, are we the same thing now? 

[3] Assign to height's value an integer other than width's value
->  height is 9 and width is 1, we are different things yet! 

[4] Assign to height the width object
->  height is 1 and width is 1, are we the same thing now? 

[5] Assign to height's value an integer other than width's value
->  height is 9 and width is 9, we are the same thing now! 

[6] Assign to height a new MyInteger and an integer other than width's value
->  height is 1 and width is 9, we are different things again! 

我们不能那么确定,因为在 [6] 对象是相同的,然后我们将一个新的对象归分给其中一个,然后,对象有不同的价值! 他们现在如何区分,如果他们是相同的? 他们应该在这里也是相同的!!!

此操作员也可以用于对象分配对象参考。

不要重复,但对于那些在阅读许多答案后仍然可能会感到困惑的人来说,有一点:

通过值在Java是不等于通过值在C++,虽然听起来像这样,这可能是为什么有混乱。

打破它:

通过值在 C++ 意味着通过对象的值(如果对象),字面上,对象的副本通过值在 Java 意味着通过对象的地址值(如果对象),而不是真正的对象的“值”(一个副本)如 C++ 通过值在 Java,在一个对象(例如 myObj.setName(“新”)在一个函数内运作的对象(例如 myObj.setName(“新”)在函数之外对对象产生影响;通过通过函数的值。

所以,朋友们,一切都只是关于术语定义的差异(通过语言),你只需要知道它是如何工作的(也许有时有点混淆它是如何称之为我承认)!

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

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

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

Java 总是通过值,而不是通过参考。

首先,我们需要了解什么是通过价值和通过参考。

Pass by reference(也称为 pass by address)是指实际参数地址的副本存储。

有时Java可以通过参考的幻觉,让我们看看它是如何工作的,使用下面的例子:

public class PassByValue {
    public static void main(String[] args) {
        Test t = new Test();
        t.name = "initialvalue";
        new PassByValue().changeValue(t);
        System.out.println(t.name);
    }
    
    public void changeValue(Test f) {
        f.name = "changevalue";
    }
}

class Test {
    String name;
}

changevalue
Let's understand step by step:

测试 t = 新测试(); 因为我们都知道它将创建一个对象,并将参考值返回t 例如,假设t 的值为 0x100234 (我们不知道实际的 JVM 内部值,这只是一个例子) 。

第一篇 描述

new PassByValue().changeValue(t);

第二个启示

如果您在函数中使用参考f 更改任何内容,则会改变对象的现有内容,这就是为什么我们在函数中更新输出变值。

要更清楚地理解这一点,请考虑下面的例子:

public class PassByValue {
    public static void main(String[] args) {
        Test t = new Test();
        t.name = "initialvalue";
        new PassByValue().changeRefence(t);
        System.out.println(t.name);
    }
    
    public void changeRefence(Test f) {
        f = null;
    }
}

class Test {
    String name;
}

这会扔一个NullPointerException吗? 不,因为它只通过一个副本的参考。 在通过参考的情况下,它可能会扔一个NullPointerException,如下所示:

希望这能帮助。