2016-01-21 31 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 ...... –

相關問題