【问题标题】:Does Java pass-by-value for arrays?Java 是否为数组传递值?
【发布时间】:2013-09-07 20:00:47
【问题描述】:

我有一个关于 Java 使用传递值的概念的问题。我用 C 语言做了很多编程,但我对 Java 非常缺乏经验,所以我一直在编写一些代码来了解更多关于它的知识。我已经阅读了许多关于是否存在任何按引用传递的堆栈溢出问题,答案似乎是 Java 总是使用按值传递(略有偏差是它按值传递对对象的引用)。

考虑到这一点,我设法正确地混淆了自己,我不明白以下示例如何成为按值传递的实例。对于我不理解的内部 Java 工作原理,我将不胜感激。

我有以下代码:

byte[] myByteArray = {23, 45, 67};
myHashMap.put(myKey, new TestClass(100, myByteArray, myOtherByteArray));
Arrays.fill(myByteArray, (byte)0);

其中myHashMapConcurrentHashMapTestClass 已定义:

public class TestClass
{
  public final int number;
  public final byte[] byte1;
  public final byte[] byte2;

  public TestClass(int a, byte[] b, byte[] c)
  {
    number = a;
    byte1 = b;
    byte2 = c;
  }
}

当我使用调试器单步执行代码时,我可以看到存储在TestClass(以及随后在ConcurrentHashMap)中的byte1 变量被Arrays.fill 调用更改,我的问题是.. 。 为什么?

当实例化一个新的TestClass 时,我不是按值传递myByteArray 吗?

【问题讨论】:

标签: java pass-by-reference pass-by-value


【解决方案1】:

所有对象都是通过传递引用来使用的,该引用本身是按值传递的,除非使用复制构造函数或 Cloneable 的 clone() 进行克隆,在这种情况下,传递对新对象的引用的值。数组也是对象,因此也是以这种方式引用的对象。如果修改了一个,则对其持有的所有其他引用都将反映这些更改。

【讨论】:

  • 嗯,不。在 Java 中,所有对象都通过 value 传递,在 SO 中这是 discussed 多次
  • 我明白了,我不知道数组被视为对象。谢谢
  • @ÓscarLópez 从技术上讲,它是对堆上对象的原始引用
  • @ÓscarLópez 准确地说,对象根本不被传递; references 被传递,它们是按值传递的。
  • @newacct 我会在这里混淆 OP 吗?帖子中显然有正确的解释,标有“好吧,技术上”。无论如何,已编辑。
【解决方案2】:

Java 是按值传递的。

总是。

唯一棘手的部分是将参数传递给方法,这在this 堆栈溢出问题中有描述。

(以下重要答案的副本)


Java 总是按值传递。很难理解 Java 将对象作为引用传递,而这些引用是按值传递的。

是这样的:

public void foo(Dog d) {
  d.getName().equals("Max"); // true
  d = new Dog("Fifi");
  d.getName().equals("Fifi"); // true
}

Dog aDog = new Dog("Max");
foo(aDog);
aDog.getName().equals("Max"); // true In this example aDog.getName() will still return "Max". d is not overwritten in the function as the object reference is passed by value.

同样:

public void foo(Dog d) {
  d.getName().equals("Max"); // true
  d.setName("Fifi");
}


Dog aDog = new Dog("Max");
foo(aDog);
aDog.getName().equals("Fifi"); // true

【讨论】:

    【解决方案3】:

    你的困惑是因为你的问题的前提是有缺陷的——“数组”不能通过。数组是对象,而对象不是 Java 中的值。 Java 中唯一的类型是原始类型和引用类型(注意:没有“对象类型”),因此 Java 中的唯一值是原始类型和引用。

    当我使用调试器单步执行代码时,我可以看到 byte1 变量存储在 TestClass 中(随后在 ConcurrentHashMap) 被 Arrays.fill 调用更改,我的问题是 ...为什么?

    您的byte1 变量没有被更改。 byte1 有一个引用类型;即它是一个参考。它的值是一个内存地址。该值保持不变。

    byte1 指向的数组对象的内容已更改。

    当实例化一个新的 TestClass 时,我不是按值传递 myByteArray 吗?

    是的,你是。

    【讨论】:

      猜你喜欢
      • 2012-12-02
      • 2012-02-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-28
      相关资源
      最近更新 更多