数组在方法中有变化吗?
我写这样的时候:
public class test { void mainx() { int fyeah[] = {2, 3, 4}; smth(fyeah); System.out.println("x"+fyeah[0]); } void smth(int[] fyeah) { fyeah[0] = 22; } }
它打印x22;
我写这样的时候:
public class test { void mainx() { int fyeah = 5; smth(fyeah); System.out.println("x"+fyeah); } void smth(int fyeah) { fyeah = 22; } }
它不打印x22,但打印x5。
为什么在第二个版本函数中,值没有变化? 它是否只更改数组元素的值?
第一个示例中的fyeah
变量包含对数组 (不是数组) 的引用 ,而第二个示例中的fyeah
整数包含整数 。
由于Java 按值传递所有内容,因此会发生以下情况:
在数组的情况下:将发送数组引用的副本,并将更改原始数组。
在int情况下:将更改整数的副本,并且不会更改原始整数。
这是因为你的int是一个原语,而smth
方法创建了一个本地副本,这就是为什么它不按你想要的方式打印的原因。 对象也按值传递,但是内存中指针的值。 因此,当它被更改时,指针会保留在两个方法中,您会看到更改。 在这里阅读更多
好。 java中的int(实际上所有具有严格数据类型的语言)都是原始数据类型。 它只是该数据类型的单个变量。 在java中,这意味着它通过值传递给方法。 因此,当您传入参数时,会创建传递的变量的副本。 方法中发生的任何操作都对该副本起作用,而不是传递的变量。
实际上在java中,EVERYTHING是通过值传递的,但是接下来我接下来要说明的实际情况的详细信息似乎是不可取的。
使用数组…它是原始数据类型int的变量集合。 因此,数组的整个副本实际上并不仅仅是对存储数组的内存的引用的副本。 所以是的,数组中int的值是从方法中的操作改变的。
简而言之,方法不会使用方法中的操作更改基元的外部值(int,float,double,long,char),如果要获取它,则必须将这些操作的结果值返回给调用者。 操作确实会使用大多数对象以及基元数组更改值。 希望有所帮助。 真的不确定得到的水平有多低。 也许其他人可以清楚地解释为什么它的价值。 我“得到”它但发现很难帮助其他人理解。
int
是一个值类型,因此5直接传递给smth
,它只能修改本地副本。 另一方面,数组是引用类型,因此可以修改该数组的元素。
从技术角度来看,我会这么说
fyeah[0] = 22;
正在改变fyeah(指向的对象)的内容
fyeah = 22;
正在改变(变量)fyeah本身。
另一个例子:
void smth(Person person) { person.setAge(22); }
正在改变这个人的内容
void smth(Person person) { person = otherPerson; }
正在更改变量person – Person的原始实例仍未更改(并且,由于Java是按值传递,因此调用代码中的变量不会被此方法更改)
从内存的角度来思考:让我们分析你的第一个程序 –
在mainx
, fyeah
是一个int
数组,所以它是一个引用(如果可能的话,还是指针)。 此引用指向堆内存中存储int
的实际数组的位置。 让我们说地址100.这里连续三个整数(从地址100开始,104和108分别是2,3和4)。
现在,您调用方法smth
并传递引用。 在该方法中,还有另一个名为fyeah
引用( int
数组类型)。 这个fyeah
与mainx
方法中的mainx
参考完全不同。 现在,当你调用smth
并从mainx
传递mainx
, smth
方法中的fyeah
被初始化为指向相同的位置(即内存地址100)当你访问fyeah
的0元素并为其赋值22时,它到达内存位置100并在那里写入该值22。 当你回到你的mainx
方法时, fyeah
引用仍然指的是内存地址100.但是那个位置的值现在是22.所以当你从fyeah
中的mainx
访问第一个元素时,你得到了这个值。
现在,你的第二个程序。 你的mainx
方法声明一个int
(不是一个数组,但是一个简单的int
)并将它设置为5.这个fyeah
变量是在不在堆上的堆栈上创建的。 值5存储在堆栈中。 现在你调用smth
并传递这个变量。 在方法smth
,你再次声明一个int
变量, fyeah
by name(作为forms方法参数)。 同样,这与mainx
方法的mainx
,这个fyeah
也是在fyeah
上创建的。这个变量将初始化为值5,从传递给smth
作为参数的fyeah
复制。 现在请注意, fyeah
变量上有两个不同的副本,两者都在堆栈上,两个值都是5.现在你将fyeah
中的fyeah
赋值为22.这不会影响mainx
方法的mainx
,所以当你返回时到mainx
并访问fyeah
,你看5。