关于JAVA方法中数组的思考
今天做一道leetcode题目时,出现了一个错误,就是在方法中修改了数组,但是在主方法中数组没有改变。我自己写了几段代码测试了一下,发现了这么一个问题,平时的数组传递的是一个地址,但是其实在方法的参数中还是一个形参,只是指向了内存中的数组,所以在修改数组的值时需要注意一个问题,就是不要将形参的引用指向别的地址。这么说可能有点抽象,上图~
就是方法的参数,传递的其实是一个地址,此时方法中的参数还是指向内存中的数组的,但是如果给这个形参指向一个新的数组,他的引用就会指向别的数组
而单个改变数组中的值就像下面这样
这样一来就不会改变形参的引用,从而达到改变原数组的目的,下面代码验证一下
public class EveryDay{
public static void main(String[] args) {
//定义一个数组
int arrs[]= {1,2,3,4,5,6};
//调用第一种方法,即改变引用指向的方法
arrayTestOne(arrs);
//输出一样,结果为123456,说明原数组没有改变
for(int i=0;i<arrs.length;i++)
System.out.print(arrs[i]);
System.out.println();
//调用第二种方法,即改变引用中的数值
arrayTestTwo(arrs);
//输出000000,说明原数组改变了
for(int i=0;i<arrs.length;i++)
System.out.print(arrs[i]);
}
//第一种方法,先开辟一块内存存放新的内容,然后给形参赋值
public static void arrayTestOne(int[] arrs) {
int[] temp = {0,0,0,0,0,0};
arrs=temp;
}
//第二种方法,依次修改数组的值
public static void arrayTestTwo(int[] arrs) {
for(int i=0;i<arrs.length;i++) {
arrs[i]=0;
}
}
}
这样可以明显看出形参的指向在第一种方法中发生了改变,第二种方法只是修改了指向内容的值,所以原数组也发生了改变。
可能这样大家都比较清楚数组的引用什么时候发生了改变,但是还有一个比较具有迷惑性的用法,需要注意一下。
public class EveryDay{
public static void main(String[] args) {
//定义一个字符数组
char[] chars = {'1','2','3','4','5','6'};
//调用第一种方法,即改变引用指向的方法
arrayTestOne(chars);
//输出一样,结果为123456,说明原数组没有改变
for(int i=0;i<chars.length;i++)
System.out.print(chars[i]);
System.out.println();
//调用第二种方法,即改变引用中的数值
arrayTestTwo(chars);
//输出000000,说明原数组改变了
for(int i=0;i<chars.length;i++)
System.out.print(chars[i]);
}
//第一种方法,先开辟一块内存存放新的内容,然后给形参赋值
public static void arrayTestOne(char[] arrs) {
String temp = "000000";
arrs=temp.toCharArray();
}
//第二种方法,依次修改数组的值
public static void arrayTestTwo(char[] arrs) {
for(int i=0;i<arrs.length;i++) {
arrs[i]='0';
}
}
}
在上面的例子中,我是调用的字符串的toCharArray()方法,查看源码
/**
* Converts this string to a new character array.
*
* @return a newly allocated character array whose length is the length
* of this string and whose contents are initialized to contain
* the character sequence represented by this string.
*/
public char[] toCharArray() {
// Cannot use Arrays.copyOf because of class initialization order issues
char result[] = new char[value.length];
System.arraycopy(value, 0, result, 0, value.length);
return result;
}
可以发现,他是先在内存中开辟了一块空间存放新的数组,然后将数组的地址引用返回,所以如果使用toCharArray方法的话,会将形参的引用指向改变,从而导致无法修改原数组的值,所以以后使用java的原生方法时要注意这点。另外,由此我们可以理解为什么java在方法中无法改变原来的字符串,因为java中string类型的字符串是不可改变的,也就是说,你无法单独改变string中的单个元素的值,只能新开辟一块内存来存放改变后的字符串,形参也因此改变,如果我们想改变string类型的字符串的话,建议将方法的返回值改为string类型,并赋给原字符串,这样原来的字符串就改变了。好了,本次思考到此结束,在思考下去我就要植发了,hh~
ps:本次思考为单纯的个人想法,如有错误之处,恳请指正