2016-01-21 49 views
4

在程序为什么从基元创建数组复制它们?

public static void main(String[] args){ 
    int x = 1; 
    int y = 2; 
    int[] z = new int[]{x, y}; 
    z[0] = 3; 
    System.out.println(x); //prints 1 
} 

我预计3将被打印。但是1。为什么?我认为Java只复制引用,即当我们将一个引用传递给一个方法时,该方法将对另一个引用同一个对象进行操作。这就像C++指针和原始类型。

所以我试着咨询JLS 10.6,没有找到任何有用的信息。也许我对Java中的原始类型有一些误解。你能澄清吗?

+0

它正确的'x'只包含值'1',所以它会打印。 – Satya

+0

不,它不像C++指针,java只是'传递值'。 – SomeJavaGuy

+0

@KevinEsche引用不像C++指针...嗯,难道你不能解释不同吗? – Alupkers

回答

11

为什么从基元创建数组复制它们?

完全相同的原因:

int a = 5; 
int b = a; 

...份a价值为b,而无需创建ab之间的任何链接:本被复制,而不是对变量的某种引用。


回复您的评论:

但是,当我们在引用类型进行操作,参考副本,不是吗?

是的,它的确如同您的int场景中复制的数字一样。

b = a(或数组初始化)的工作原理完全相同的方式不管ab是否是原始类型的变量或引用类型的变量:该a复制b,再有是ab之间没有正在进行的链接。

唯一的区别是,当你处理参考类型时,变量中的值不是实际的东西,它实际上是一个参考。因此,复制从一个变量,它引用到另一个只是让让这两个变量指的是同样的事情,就像我上面的代码使ab都有值5

考虑:让我们创建一个列表:

List<String> a = new ArrayList<String>(); 

这使我们在存储器是这样的:

 
       +----------+ 
a(55465)----->| the list | 
       +----------+ 

可变a包含一个值,它是对一个对象的引用。我已经将上面的值描述为55465,但我们实际上从未真正看到Java代码中的原始值(并且随着垃圾回收的完成而变化)。它只是一个值,就像任何其他值一样,它告诉JVM在内存中查找对象的位置。你可以把它想象成一个包含内存地址的long(这不是真的,但它在概念上起作用)。

现在我们做到这一点:

List<String> b = a; 

现在我们必须在内存中是这样的:

 

a(55465)--+ 
      | +----------+ 
      +--->| the list | 
      | +----------+ 
b(55465)--+ 

两个ab包含这是指到列表中。

你可以看到这是完全一样:

int a = 5 

给我们

 
a(5) 

然后

int b = a; 

给我们

 
a(5) 
b(5) 

在变量之间被复制,传入函数等。与引用类型的唯一区别是该值用于什么,它是如何解释的。

如果是这样,我会说java复制了原始值和引用类型的值。对?

号“通过值”和“按引用传递”在计算特定的含义:这是关于具有与可变,而不是一个对象的引用。这就是传递参考的样子:

// NOT JAVA; Java doesn't have this 
void foo(int &a) { // Fake pass-by-reference thing 
    a = 3; 
} 

int a = 5; 
foo(&a); // Fake pass-by-reference operator 
System.out.println(a); // 3 

传递引用与对象引用无关。他们唯一的共同点就是“参考”这个词。 Java是一种纯粹通过价值的语言。

+0

但是,当我们在参考类型上操作参考副本时,不是吗?如果是这样的话,我会说在复制基元的值和引用类型的引用的意义上,java是按值传递的。对? – Alupkers

+7

@Alupkers:它在每种情况下都复制变量的值 - 只是在引用类型中,变量*的值是引用而不是对象。另请参阅:http://stackoverflow.com/questions/32010172/what-is-the-difference-between-a-variable-object-and-reference/32010236#32010236 –

+0

@Alupkers:我已更新答案以回答你的评论。 –

0

Java是通过值没有引用。如果分配给数组零,所以它不会被分配到x

-1

你没有错误的位置:

int x = 1; 
int y = 2; 
int[] z = new int[]{x, y}; 
z[0] = 3; 
System.out.println(x); //prints 1 // You are printing x (where x = 1) 

在这里,您打印x所以x = 1

如果您打印z[0]代替x然后将打印3

+1

有没有错误,他质疑它为什么这样工作,而不是他做错了什么 –

-1

z[0] = 3值分配给数组不int x

+0

抱歉,关于那个先生米新到stackoverflow ...... –

相关问题