java关于传值的一种特殊情况

啥话我也不说了,直接上代码吧!

public class Test {
    public static void main(String[] args) {
        String str = new String("abc");
        change1(str);
        System.out.println(str);
    }
    
    private static void change1(String str1) {
        str1 += "123";
        System.out.println(str1);
    }
}

输出的结果是:
abc123
abc

我相信很多java程序员都知道,对象是传递引用,基本数据类型才是传递值,但是这里为什么在main中还是输出的abc呢?

原因是这样的,在这次调用中,等于声明了两个变量str,str1,它们指向的是同一个地址,调用change方法,只是将str指向的地址传递给了str1,而str本身并没有传递过去(也就是没有传递引用),当你重新赋值的时候(也就是将对象引用指向其他存储空间),等于只影响了str1,而没有影响str。 
这样的传递方式只能称之为址传递,或者是引用对象传递,而不能说是传递引用或者引用传递。 
我不知道这究竟属于翻译的错误,还是我们理解的错误。但是这样的问题在c++中是有明显的区分的(通过*与&)

我想这个可以一句话表明:对于引用类型 str,赋值运算符会改变引用中所保存的地址,原来的地址被覆盖掉。但是原来的对象不会被改变(重要)。所以str1其实是一个新的地址了,而不是str的地址!!!!

public static void main(String[] args) {
		int[] array = {1,2,3,4};
		change(array);
		System.out.println("this array:");
		for(int i=0;i<array.length;i++){
			System.out.println(array[i]);
		}
	}
	private static void change(int[] arr){
		
		for(int i=0;i<arr.length;i++){
            arr = i*2+1;
			System.out.println(arr[i]);
		}
	}

那么我们再看看这段代码,这个代码输出的是:

1 3 5 7
1 3 5 7
这个时候就符合对象传递引用了,那么下面我们把代码稍微改动一下:

public static void main(String[] args) {
		int[] array = {1,2,3,4};
		change(array);
		System.out.println("this array:");
		for(int i=0;i<array.length;i++){
			System.out.println(array[i]);
		}
	}
	private static void change(int[] arr){
		int[] temp = new int[]{5,6,7,8};
		arr = temp;
		for(int i=0;i<arr.length;i++){
			System.out.println(arr[i]);
		}
	}

结果:

5 6 7 8
1 2 3 4
在方法中构建了一个新的对象,但是为什么在main方法中却还是输出原来的值呢?

我的理解是:因为temp是一段新的内存地址,因为是在方法中new出来的嘛,所以这个时候参数arr = temp,就是指向了temp的首地址,但是原来array的地址是没有变的,也没有被销毁,所以输出的自然就是原来的内存中的值了!

猜你喜欢

转载自blog.csdn.net/xdxx152/article/details/82767471