这是我参与8月更文挑战的第13天,活动详情查看:8月更文挑战
前言
今天日常摸鱼的时候,群里闲聊,有人问JAVA中参数传递的时候,传递的是参数值还是引用?当时第一反应有点闷,想到了基本类型和引用类型,回了句好像是基础类型是值传递,引用类型是引用传递,好像说了,又好像什么也没说,群里也没有给出权威性的答案,然后我网上冲浪一番后,给出我的答案。
Java是值传递!Java是值传递!Java是值传递!
论证
无论是基本类型具体值还是引用类型的引用地址值都是值传递。
口说无凭,我们敲代码证明一下 看下面这个例子
package com.yang.passbyvalue;
import java.util.Arrays;
/**
* 基本数据类型传的是克隆的一个值,
* 引用类型传的是克隆指向对象地址值的一个值
*/
public class Demo {
public static void change(int a) {
a = 2;
System.out.println("我是方法里的a:" + a);
}
public static void changArray(int[] data) {
data[0] = 3;
data[1] = 4;
System.out.println("我是方法里的data:" + Arrays.toString(data));
}
}
class Test {
public static void main(String[] args) {
//初始化基本数据类型
int a = 0;
System.out.println("我是初始化的a:" + a);
Demo.change(a);
System.out.println("我是change后的a:" + a);
//初始化引用数据类型
int[] data = {1, 2};
System.out.println("我是初始化的data:" + Arrays.toString(data));
Demo.changArray(data);
System.out.println("我是change后的data:" + Arrays.toString(data));
}
}
定义一个基础类型
a=1
调用change()
将赋值改为2
,然后定义一个引用类型数据,然后调用changArray()
将数组中的值修改掉,然后分别打印方法调用前和调用后的结果。 我们可以带着心里的答案去验证一下。
我是初始化的a:0
我是方法里的a:2
我是change后的a:0
我是初始化的data:[1, 2]
我是方法里的data:[3, 4]
我是change后的data:[3, 4]
结果,基础类型值没有改变,引用类型值随方法改变而改变了
基础数据类型传递的是一份数据拷贝,所以在
change()
里修改了方法里的a
的值并不会影响初始值,而对于数组(引用类型),changArray()
修改了地址引用指向的对象的值,所以原来引用指向该对象的值都随之改变了。
看到这里,貌似我最初的解释是合理的,心里有点小窃喜,但是,事实并不是这样。 再来看看下面这个例子
package com.yang.passbyvalue;
public class StringDemo {
public static void change(String s) {
s = "aaa";
System.out.println("我是方法里的s:" + s);
}
}
class StringDemoTest {
public static void main(String[] args) {
String s = "a";
System.out.println("我是初始化的s:" + s);
StringDemo.change(s);
System.out.println("我是修改后的s:" + s);
}
}
我是初始化的s:a
我是方法里的s:aaa
我是修改后的s:a
String
类型作为引用数据类型,为什么在方法里修改了,但是没有影响原先的值?
我们知道
String
不可变,String
底层是被final
修饰的char[]
,值是不能被修改的。
字面值
"a"
初始化的时候,会先将"a"
放进字符串常量池中,s
保存的是引用地址值,当调用change()
方法时,将地址值传过去,s = "aaa";
会先去常量池中找"aaa"
,找到返回"aaa"
的地址引用,找不到创建一个"aaa"
,返回新建的"aaa"
的地址引用,新的引用覆盖传过来的引用s
,但是初始化的s
任然保存的是指向"a"
的地址引用。这恰恰说明了 Java 里是值传递。
总结
有些时候我们觉得掌握的知识并不一定可靠,正是因为很多这种模糊导致了我们在工作或者面试时候的不自信,从另一方面也反映出来自己基础的不扎实,后期这块还是要不断加强,不断学习。