在写之前先介绍几个基础的知识点
基础知识点:
基本数据类型:
整型:byte,short,int,long
浮点型:float,double
字符型:char
布尔型:boolean
引用数据类型:
数组
类
接口
方法的参数分为实际参数个形式参数(实参和形参)。
形式参数:定义方法时写的参数
实际参数:调用方法时写的具体数值
一般情况下,在数据作为参数传递的时候,基本数据类型是值传递,引用数据类型是引用传递(地址传递)
值传递
int num1 = 10;
int num2 = 20;
swap(num1, num2);
LogUtil.fussenLog().d("num1 = " + num1);
LogUtil.fussenLog().d("num2 = " + num2);
}
private void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
LogUtil.fussenLog().d("a = " + a);
LogUtil.fussenLog().d("b = " + b);
}
运行结果是:
原因
流程:
1主函数进栈,num1 num2 初始化
2调用swap方法,swap()进栈,将num1 num2 的值复制一份给a, b
3方法中对a,b的值进行交换
4方法执行完毕,a b的值已经交换
5swap方法弹栈
6主函数弹栈
解析:
在swap方法中,a,b的值进行交换,并不会印象到num1 , num2 。因为a , b 的值只是从num1 , num2 的复制过来的。
也就是说 a,b 相当于 num1 , num2 的副本,副本的内容无论怎么修改,都不会影响到与原件本身。
引用传递
int[] arr = {1, 2, 3, 4, 5};
change(arr);
LogUtil.fussenLog().d(arr[0]);
}
private void change(int[] array) {
array[0] = 0;
}
最终运行结果:
原因
流程:
1.主函数进栈,int【】 arr初始化
2调用change 方法 change()进栈,将arr 的地址值 , 复制一份给array
3方法中,根据地址值,找到堆中的数组,并将第一个元素的值改为0
4方法执行完毕,数组中的第一个值已经改变
5change方法弹栈
6主函数弹栈
解析:
调用change()的时候,形参array接收的是arr地址值的副本,定在change方法中,通过地址值,对数组进行了操作。change方法弹栈以后,数组中的值已经改变。main 方法中,发印出来的aar【0】 也就是从原来的1 变成0 、
无论时主函数还是change方法,操作的都是同一个地址只对应的数组。
就想你把自己家钥匙交给了另一个人,这个人拿着钥匙在你家一顿折腾,然后走了,等你拿着钥匙回到家以后,家里已经变成被折腾之后,惨不忍睹的样子。。。
这里的钥匙就相当于地址值,家就相当于数组本身。
String 类型传递
String str = "AAA";
change(str);
LogUtil.fussenLog().d(str);
}
private void change(String s) {
s = "abc";
}
执行的结果是:
这就神奇了,String 是一个类,类是引用数据类型,作为参数传递的时候,应该是引用传递。但是从结果上看起来却是值传递。
原因:
String Integer Double 等 immutable类型的特殊处理,可以理解为值传递,最后的操作不会修改实参对象。
--------------------------------------------------------------------------------------------------
结论:
(1)基本数据类型传值,对形参的修改不会影响实参;
(2)引用类型传引用,形参和实参指向同一个内存地址(同一个对象),所以对参数的修改会影响到实际的对象;
(3)String, Integer, Double等immutable的类型特殊处理,可以理解为传值,最后的操作不会修改实参对象。