简述一下值传递和引用传递的概念
简介一下形参和实参
形参:即每个方法的参数,如下代码value就是一个形参
public static int f(int value) {
try {
return value * value;
} finally {
if (value == 2) {
return 0;
}
}
}
实参:调用方法时传的参数,如下代码就是括号内部就是实参
f(1)
值传递概念
值传递的概念也很简单,说白了形参会将实参的值拷贝一份作为自己的值来使用,自己无论怎么改变都不会影响到实参的值,具体示例下文会补充。
引用传递概念
这个概念在c++、c#中才有,简单来说就是将实参所指向的变量的地址传给形参,这样形参操作的就是实参所指向的变量的值,一旦形参改变那个值,实参看到的值也是有变化的。
java常见的值传递两种示例
基本类型的值传递
代码示例
可以看到下面代码将实参将值赋给形参后,形参无论如何交换对实参都没有任何作用
public static void main(String[] args) {
int num1 = 10;
int num2 = 20;
swap(num1, num2);
System.out.println("num1 = " + num1);
System.out.println("num2 = " + num2);
}
public static void swap(int a, int b) {
int temp = a;
a = b;
b = temp;
System.out.println("a = " + a);
System.out.println("b = " + b);
}
输出结果
a = 20
b = 10
num1 = 10
num2 = 20
图解基本类型的java值传递过程
java引用类型值传递
代码示例
如下代码所示,将引用类型传给形参后发现实参的值被改变了,很多认为这明明就是引用类型传递。
但是事与愿违,这里必须清楚一个java引用类型的值传递的机制,对于基本类型直接拷贝值,而对于引用类型,他做的是拷贝引用类型变量的地址,而引用传递做的是拷贝引用类型所指向的空间的值,听到这里是不是觉得很混乱?没关系我们在写一段代码示例就知道了
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5 };
System.out.println(arr[0]);
change(arr);
System.out.println(arr[0]);
}
public static void change(int[] array) {
// 将数组的第一个元素变为0
array[0] = 0;
}
输出结果
1
0
代码示例2
可以看到person这种引用类型作为实参传入后,对象xiaozhang和xiaoli的名字没有被交换,这就说明了java对引用类型做的也是值传递,传递的引用类型的地址值。我们不妨以一张图来说明
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
Person xiaoZhang = new Person("小张");
Person xiaoLi = new Person("小李");
swap(xiaoZhang, xiaoLi);
System.out.println("xiaoZhang:" + xiaoZhang.getName());
System.out.println("xiaoLi:" + xiaoLi.getName());
}
public static void swap(Person person1, Person person2) {
Person temp = person1;
person1 = person2;
person2 = temp;
System.out.println("person1:" + person1.getName());
System.out.println("person2:" + person2.getName());
}
}
图解对于java如何实现引用类型值传递
参考文献
为什么 Java 中只有值传递?
JavaSE-面向对象思想、原理以及内存图解