小编近期在学习Java中方法的参数传递时难以理解,相信大家也和小编一样对什么是值传递和地址传递很困扰。
1、值传递:
Java中当基本数据类型作为方法的参数时是按值传递,按值传递意味着将基本数据类型变量的副本传递给方法。对副本所作的任何更改都不会影响原始变量。这里值得注意到的是这个副本到底是什么接下来由小编为大家讲解。
副本:是指创建和原始对象的完全独立的新对象,对副本所做的任何操作,都不会影响原始对象。
我相信这样解释还有很多码友还是不能理解,接下来小编就给你们打个比方:基本数据类型作为形参时就好比你有张纸上有非常重要数据,而你的女儿非要在这张纸上画画,这时候机智的爸爸想到了复印。于是产生两全其美的结果,你的珍贵的数据没有被摧毁而你的也女儿心满意足的画上画。这样我们就能很好的理解为什么值传递后原来的值不变。
图片示例:
代码示例:
public class Switch {
public static void main(String[] args) {
int x1 = 10;
int y1 = 20;
// 交换前输出
System.out.println("交换前x1 = "+x1);
System.out.println("交换前y1 = "+y1);
// 进行数据交换
swap(x1, y1);
// 交换后输出的结果不变
System.out.println("交换后x1 = "+x1);
System.out.println("交换后y1 = "+y1);
}
public static void swap(int x, int y) {
int z1 ;
z1 = x;
x = y;
y = z1;
System.out.println("x = "+x);
System.out.println("y = "+y);
}
}
运行结果:
2、引用传递:
Java中当引用数据类型作为方法的参数时是按地址传递(或引用传递),按地址传递意味着将引用数据类型变量的地址传递给方法,对地址进行任何修改都会影响原始变量。同样这里值得注意到的是这个引用到底是什么接下来由小编为大家讲解。
引用:是指向对象的内存地址的指针,对引用的更改不会创建新对象,而是更改指向的对象。
我相信这样解释还有很多码友还是不能理解,接下来小编就给你们打个比方:引用数据类型作为形参时相当于两个人共用一个有地址编号的盒子,这个盒子可以存放定量的东西。当任意一人对盒子内东西进行操作时,那么无论之后谁在使用时盒子内的东西都已经发生改变。这样我们就能很好的理解为什么地址传递后原来的值改变。
图片示例:
小编画这个是为帮助大家理解的,如果画上z[0]显得臃肿违背我的本意,故在此小编在堆中省略z[0]交换实现交换的过程(就两个值通过一个变量实现交换)。
代码示例:
public class Switch {
public static void main(String[] args) {
int [] x1 = {10};
int [] y1 = {20};
// 交换前输出
System.out.println("交换前x1 = "+x1[0]);
System.out.println("交换前y1 = "+y1[0]);
// 进行数据交换
swap(x1, y1);
// 有趣的是交换后输出的结果并没有发生改变
System.out.println("交换后x1 = "+x1[0]);
System.out.println("交换后y1 = "+y1[0]);
}
public static void swap(int [] x, int [] y) {
int z = x[0];
x[0] = y[0];
y[0] = z;
System.out.println("x = "+x[0]);
System.out.println("y = "+y[0]);
}
}
运行结果:
别急,有趣的是小编在准备代码示例素材时想用类引用数据类型String来讲解却发现不行,这是为什么呢?
代码示例:
public class Switch {
public static void main(String[] args) {
String x1 = "10";
String y1 = "20";
System.out.println("交换前x1 = "+x1);
System.out.println("交换前y1 = "+y1);
// 进行数据交换
swap(x1, y1);
// 有趣的是交换后输出的结果并没有发生改变
System.out.println("交换后x1 = "+x1);
System.out.println("交换后y1 = "+y1);
}
public static void swap(String x, String y) {
String z ;
z = x;
x = y;
y = z;
System.out.println("x = "+x);
System.out.println("y = "+y);
}
}
运行结果:
这里我们注意到执行函数操作后原来的值并没有发生改变,理论上应该发生改变。这是为什么呢?String是一种特殊的引用数据类型,他是不可变的。这意味着当你对一个String对象进行修改时,实际上是创建了一个新的String对象,而不是在原有对象上进行修改。(可以按值传递方式理解)