简体   繁体   English

Java中的奇怪数组行为。 具有单个int的数组的行为与具有int不在数组中的同一程序的行为不同

[英]Strange array behaviour in java. An array with a single int behaves differently than the same program with the int not in an array

Why is there a difference between the following two programs A & B. Shouldn't they run identical? 为什么以下两个程序A和B之间有区别。它们不应该运行相同吗? For some reason the changer in the case of the array is changing the original value of the input array. 出于某种原因, changer在阵列的情况下,改变所述输入数组的初始值。

Program A: 程序A:

public static void changer(int tester) {
    tester = tester*2;
}

public static void main() {

    int value = 1;
    out.println(value);
    changer(value);
    out.println(value);     
}

which gives me the output: 这给了我输出:

1
1

Program B: 程式B:

public static void changer(int[] tester) {
    tester[0] = tester[0]*2;
}

public static void main(){

        int[] value = {1};
        out.println(value[0]);
        changer(value);
        out.println(value[0]);


}

which gives me the output: 这给了我输出:

1
2

Changing a value in a called method does not change the value in the calling method. 在被调用方法中更改值不会更改调用方法中的值。 In Program B, you're not changing the array, you're changing a value inside the array, and that is visible in the calling method. 在方案B,你不改变数组,你改变了数组内的值,并且在调用方法可见。

In your first example, you passed an int (tester) to the function, and then assigned a new value to it. 在第一个示例中,您向该函数传递了一个int(测试器),然后为其分配了一个新值。 Since java is pass-by-value, assignment has not effect outside of the callee scope, and so the original value was not changed in the call site. 由于java是按值传递,因此赋值不会在被调用方范围之外起作用,因此在调用站点中未更改原始值。

In the second example, you passed an int array to the function, and then you did not assign to it, but modeified its content, by assigning to a specific cell inside of it, so the value was changed in the call site as well. 在第二个示例中,您将一个int数组传递给该函数,然后您没有分配给它,而是通过分配给函数内部的特定单元格来对其内容进行审核 ,因此该值也在调用站点中进行了更改。

Passing primitive data type ( ie int, double, long, float, ....) to a function or method will be " PASSED BY VALUE". 将原始数据类型(即int,double,long,float等)传递给函数或方法将是“ PASSED BY VALUE”。 In program A, the argument passed to method is a primitive data (int), so you just passed a copy of the origin value. 在程序A中,传递给方法的参数是原始数据(int),因此您仅传递了原始值的副本。 Any change to it, will not affect the origin number. 对其进行任何更改都不会影响原产地编号。

But passing Reference/Object data type (ie, Array, ArrayList, HashMap,...) to a function will be " PASSED OBJECT BY VALUE," which means the method is given copy of the reference to the object. 但是将Reference / Object数据类型(即Array,ArrayList,HashMap等)传递给函数将是“ PASSED OBJECT BY VALUE”,这意味着该方法将获得对对象的引用副本。 So any change to it, will change the origin reference. 因此,对它的任何更改都会更改原点参考。 In program B, you passed a reference copy of an array. 在程序B中,您传递了数组的参考副本。 That is why it has been modified. 这就是为什么它已被修改。

When arrays work like pointers. 当数组像指针一样工作时。 When you use 使用时

tester[0] = tester[0]*2;

You are basically telling compiler to update element in memory on location tester[0] 您基本上是在告诉编译器更新位置tester[0]上内存中的元素

This question had been asked so many times. 这个问题被问了很多遍了。 Java passes everything by value and this is especially true for primitive such as int . Java通过值传递所有内容,对于int原始语言尤其如此。

When you pass an int argument, you are passing in the value, not the reference of the variable. 传递int参数时,您传递的是值,而不是变量的引用。

public static void main(String[] args){
    int value= 5;
    changer(val);
}
public static void changer (int tester){
    //A variable call tester holding the value of 5
}

A local variable call tester with value of 5 will be created, because you passed in a value of 5. Variable val itself was not passed in. 将创建一个值为5的局部变量调用tester ,因为您传入的值为5。变量val本身未传入。

Any changes done within the method is merely changing the local variable tester . 方法内所做的任何更改都仅是更改局部变量 tester This explains why the value of val remains unchanged. 这解释了为什么val的值保持不变。


When you pass in an array, it still passes by value , but the value does not contain all the values of individual array element. 当您传递数组时,它仍按value传递 ,但该值不包含单个数组元素的所有值。 It will be very inefficient to copy the entire array's value for every method invocation. 对于每个方法调用,复制整个数组的值将非常低效。 The value holds the reference of the array. 该值保存数组的引用。 Thus, tester now holds the reference of the val . 因此, tester现在拥有val的引用。

public static void main(String[] args){
    int[] val= 5;
    changer(val);
}
public static void changer (int[] tester){
    //A variable call tester holding the reference of val array.
}

Since tester is now pointing at the original array: val . 由于测试器现在指向原始数组: val Anything you changed in the method will affect the original array. 您在方法中所做的任何更改都会影响原始数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM