Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在方法中更改数组将更改外部数组_Java_Variables_Scope - Fatal编程技术网

Java 在方法中更改数组将更改外部数组

Java 在方法中更改数组将更改外部数组,java,variables,scope,Java,Variables,Scope,我对变量的范围有问题 public static void main(String[] args){ int[] test={1,2,3}; test(test); System.out.println(test[0]+" "+test[1]+" "+test[2]); } static void test(int[] test){ test[0]=5; } 我期望输出为123code>,但结果是523。 为什么我更改了方法中数组中的值,但更改了原始数组?定义

我对变量的范围有问题

public static void main(String[] args){
    int[] test={1,2,3};
    test(test);
    System.out.println(test[0]+" "+test[1]+" "+test[2]);
}

static void test(int[] test){
    test[0]=5;
}
我期望输出为
123code>,但结果是
523
。 为什么我更改了方法中数组中的值,但更改了原始数组?

定义:

  • Reference=指向数组所在内存位置的变量
  • 引用值=实际内存地址位置本身
您将数组引用的值传递到
test()
方法中。因为java是按值传递的,所以它传递的是引用的值,而不是数组的值(即副本)

如果您有C语言背景,则更容易将引用视为指针。所以一个引用的值本质上就是它的内存地址(我在这里捏造java规则,但这样想可能最简单)

因此,在您的示例中,将指向数组的引用值传递到
test()
方法中,然后该方法使用该引用值查找数组在内存中的位置,以便它可以访问数组中的数据


由于在
test()
方法中没有更改数组的引用(它指向的位置,即
test=new int[10];
),因此
test()
方法作用于数组中的原始数据(因为它仍然指向原始数组的位置),导致元素
0
被设置为
5
的值

Java中的数组是一个对象。当您通过
new
创建数组时,它将在堆上创建,并返回一个参考值(类似于C中的指针)并分配给您的变量

在C中,这将表示为:

int *array = malloc(10 * sizeof(int));
将该变量传递给方法时,传递的是分配(复制)给方法中本地(堆栈)变量的引用值。不会复制数组的内容,只复制引用值。同样,就像在C中向函数传递指针一样

因此,当您通过该引用修改方法中的数组时,您正在修改堆上存在的单个数组对象

您评论说您通过
int[]temp=test
创建了阵列的“副本”。。。同样,这只生成指向内存中单个数组的引用值(指针)的副本。现在有三个变量都持有对同一数组的相同引用(一个在
main()
,两个在方法中)

如果要制作数组内容的副本,Java提供:


这将在堆上分配一个新的数组对象(大小由第二个参数指定),将现有数组的内容复制到该对象,然后将对该新数组的引用返回给您

因为您正在修改对象的状态…请不要被参数的名称弄糊涂。在
测试(…)
方法中将参数名称更改为
无论什么,它都不会影响任何内容。对于OP:这与范围无关。您将一个对象引用值传递给一个方法,并通过该方法内的引用修改该对象。这就是Java(和C,以及…)的工作原理。请看:@SotiriosDelimanolis,这将通过值传递,如果您仔细考虑(我的意思是,考虑只传递数组的值),这将是正确的。但是您会传递一个引用的副本,因此如果您更改了对象的状态(在本例中是数组中的一个条目),那么原始对象也会被修改。
int[]temp=test
不会创建新的数组对象,它只会将数组引用(即指针)从“test”复制到“temp”.每当有人说传递值“令人困惑”时,我就完全困惑了。C按值传递指针。Java做了完全相同的事情。通过进一步混淆,比如说OP的
test
方法包含
test=new int[]{7,7,7}
,本质上创建了一个新数组并将指针重定向到该数组。为什么这次外面的阵列没有改变?
int[] newArray = Arrays.copyOf(test, test.length);