Java是否为数组传递值?

时间:2013-09-07 20:00:47

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

我对使用pass-by-value的Java概念有疑问。我在C中做了很多编程,但是我对Java非常缺乏经验,所以我一直在编写一些代码来学习更多关于它的知识。我已经阅读了许多关于是否存在任何pass-by-reference的堆栈溢出问题,答案似乎是Java总是使用pass-by-value(稍有偏差是它通过值传递对象的引用)。 / p>

考虑到这一点,我设法正确地混淆了自己,我不明白以下示例如何成为传值的实例。我很感激对我不理解的内部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;
  }
}

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

在实例化新的Arrays.fill时,我没有按值传递TestClass吗?

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

  

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

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

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

  

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

是的,你是。