为什么数组中的元素可以改变值,但原始类型的值不能改变?(无法弄清楚一个好的标题,对不起)

时间:2014-03-22 08:31:17

标签: java

请参阅代码(Java):

public static int[] array(){
     int[]arr={0,1};
     changeArr(arr);
     return arr;
}
public static void changeArr(int[]arr){
    arr[0]=100;
    arr[1]=101;
}

然后我在arr []中打印元素,我发现arr [0]变为100,并且arr [1]变为101,我知道正确,因为方法changeArr()改变了值。

然而,

public static int m(){
   int m=0;
   changeM(m);
   return m;
}
public static void changeM(int m){
   m=100;
}

为什么m的值不会改变?如果我打印m,m仍然是0,它不会改为100,为什么? 为什么数组中的元素可以改变,但原始类型m不会改变?

3 个答案:

答案 0 :(得分:2)

Java按值传递参数。这意味着创建了参数的副本,并将此副本传递给该方法。对于数组,复制的是数组的引用(或指针,如果您愿意)。所以你得到以下内容:

在方法调用之前:

arr --------> [1, 2]

在方法调用期间,在分配之前:

arr --------> [1, 2]
               ^
               |
arr-copy -------

在方法调用期间,在分配之后:

arr --------> [100, 101]
               ^
               |
arr-copy -------

方法调用后:

arr --------> [100, 101]

传递基元时,原始值本身会被复制。

在方法调用之前:

m ========  0

在方法调用期间,在赋值之前:

m ========= 0


m-copy ==== 0

在方法调用期间,在赋值后:

m ========= 0


m-copy ==== 100

方法调用后:

m ========= 0

答案 1 :(得分:0)

在第二种情况下m通过值传递,因此它仅在方法内部更改。在第一种情况下,arr通过值传递,它只是引用数组而不是整个数组对象。因此,更改arr[i]将在方法之外进行更改。但如果你做arr = some other array它就像第二种情况一样,那么方法中的更改仍然存在。

答案 2 :(得分:0)

在Java函数调用中,参数由"值复制"传递。

  • (1)对于基本类型(int / float / long / double ...),"值的复制"表示那些原始类型的副本。现在有2个数据:调用者中的原始数据和被调用者中的副本数据。它们的内容是相同的,但地址(在内存中)是不同的,所以你改变副本不会影响orignal。

  • (2)对于引用类型(对象/数组),表示其引用的副本(类似于"指针"在C / C ++中)。现在有两个引用,原始的一个在调用者中,副本一个在被调用者中。即使它们是2个单独的引用(地址不同),但它们的内容是相同的(内容是对象/数组的地址)。因此,它们中的任何一个都是访问相同对象/数组的关键。

请参阅下面的评论:

public static int[] array(){
     int[]arr={0,1};  // arr is a reference(pointer) to [0,1]
     changeArr(arr);  // copy the reference and pass to changeArr()
     return arr;
}
public static void changeArr(int[]arr){ // Get the copy of reference, the copy also point to [0,1].
    arr[0]=100;  // Use the reference as a key to change the array [0,1]
    arr[1]=101;  // Use the reference as a key to change the array [0,1]
}

public static int m(){
   int m=0;  // m is a primitive type(int), it stays in its own address(eg. A1).
   changeM(m);  // Make a copy of m(we call it m'), the content of m' is 0, but its address(A2) is different from m. Pass m' to changeM().
   return m;
}
public static void changeM(int m){  // Get m'.
   m=100;  // No matter how to change m', will not affect m, because they are individual.
}