概述:
一般认为,数据参数传递时,基本数据类型是值传递,引用数据类型是引用传递(地址传递)。
- java中数据类型包括基本数据类型和引用数据类型
基本数据类型
整型:byte,short,int,long
浮点型:float,double
字符型:char
布尔型:boolean
- 引用数据类型
数组
类
接口
- 方法的参数分为实际参数和形式参数。
值传递举例:形式参数:定义方法时写的参数。
实际参数:调用方法时写的具体数值。
public static void main(String[] args){
int n = 6;int m = 8;
exchange(n,m);
System.out.println("n=" +n);
System.out.println("m=" +m);
}
public static void exchange(int a, int b){
int temp = a;
a = b;
b = temp;
System.out.println("a=" +a);
System.out.println("b=" +b);
}
输出结果:
a=8
b=6
n=6
m=8
解析:- 主函数进栈,n、m初始化;
- 调用exchange方法,exchange( )进栈,将n和m的值,分别赋值给a和b;
- 在exchange方法中,a、b的值进行互换;
- exchange方法执行完毕,a、b的值已经交换,方法弹栈;
- 主函数main()弹栈。
在exchange方法中,a、b的值进行交换,并不会影响到n、m的值。因为a、b中的值,只是从n、m复制过来的。
也就是说,a、b相当于n、m的副本,副本的内容无论怎么修改,都不会影响到原始数据。
引用传递举例:
public static void main(String[] args) {
int[] arr = {1,2,3};
swap(arr);
System.out.println("arr[0]=" +arr[0]);
}
//将数组的第一个元素变为6
public static void swap(int[] a) {
a[0] = 6;
}输出结果:
arr[0]=6
解析:
- 主函数main()进栈,int[] arr初始化。
- 调用swap()方法,swap()进栈,将arr的地址值,赋值给a。
- 在swap()方法中,根据地址值,找到堆中的数组,并将第一个元素的值改为6。
- swap()方法运行完毕,数组中第一个元素的值已经改变,方法弹栈。
- 主函数main()弹栈。
调用swap()的时候,形参a接收的是arr地址值的副本。并在swap()方法中,通过地址值对数组进行操作。swap()方法弹栈以后,数组中的值已经改变。main方法中,打印出来的arr[0]也就从原来的1变成了6。无论是主函数,还是swap()方法,操作的都是同一个地址值对应的数组。
String例外举例 :
public static void main(String[] args) {
String str = "CC";
exchange(str);
System.out.println(“str=” +str);
}
public static void exchange(String s) {
s = "cc";
}
输出结果:
str= CC
解析:
- 主函数进栈,str初始化;
- 调用exchange方法,exchange( )进栈,将str的地址值,赋值给s;
- 在exchange方法中,重新创建了一个String对象”cc”,并将s指向了新的地址值;
- exchange方法执行完毕,s所指向的地址值已经改变,方法弹栈;
- 主函数main()弹栈。
String对象做为参数传递时,依然是引用传递,只不过String这个类比较特殊。 String对象一旦创建,内容不可更改。每一次内容的更改都是重新创建出来的新对象。 当exchange方法执行完毕后,s所指向的地址值已经改变。而s本来的地址值就是复制过来的副本,所以并不能改变str的值。
总结:
(1)“在Java里面参数传递都是按值传递”这句话的意思是:按值传递是传递的值的拷贝,按引用传递其实传递的是引用的地址值,所以统称按值传递。
(2)在Java里面只有基本类型和String,Integer, Double等immutable类型(immutable类型没有提供自身修改的函数,每次操作都是新生成一个对象,所以要特殊对待,可以认为是传值)是按值传递,其它的都是按引用传递。