Java|Java 值传递 or 引用传递()
Java 方法传参 值传递 or 引用传递?
结论:Java采用的是值传递先建立一些基础的概念
什么是值传递和引用传递?
- 值传递(pass by value):是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数
- 引用传递(pass by reference):是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数
- 基本类型(int float等)
- 引用类型(string, 数组等, 以及一切类对象)
文章图片
实践出真知,本文做了三个实验来论证为什么Java是值传递。
实验一:证明基本类型是值传递
先上代码
public class test {public static void main(String[] args) {
int a = 1000;
changeInt(a);
System.out.println("(main)a = " + a);
}private static void changeInt(int a) {
a = 3;
System.out.println("(changeInt)a = " + a);
}
}// 运行代码会得到如下结果
// (changeInt)a = 3
// (main)a = 1000
在代码中,我们向
changInt
方法传入了变量a
,并在方法内部中改变了a
的值,但主程序中a的值并没有改变。因此基本类型是值传递。实验二:引用类型是引用传递?
先上代码
public class test {
public static void main(String[] args) {
Student std = new Student();
std.name = "Nick";
changeStd(std);
System.out.println("(main)name = " + std.name);
}private static void changeStd(Student std) {
std.name = "Paul";
System.out.println("(change)name = " + std.name);
}
}class Student {
String name;
}// 运行结果
// (change)name = Paul
// (main)name = Paul
在上段代码中,我们向
changeStd
方法传入了一个student
类实例,并在方法内部中改变了学生类实例中的name
字段。从运行的结果我们可以看出主程序中的学生实例的姓名也被改变。难道引用类型采用的是引用传递?当然不是,接下来继续看第三个实验。实验三:引用类型是值传递?
public class test {
public static void main(String[] args) {
Student std = new Student();
std.name = "Nick";
changeStd(std);
System.out.println("(main)name = " + std.name);
}private static void changeStd(Student std) {
std = new Student();
std.name = "Paul";
System.out.println("(change)name = " + std.name);
}
}class Student {
String name;
}// 运行结果
// (change)name = Paul
// (main)name = Nick
我们改变了方法内部的赋值,我们先重新给
std
创建了一个新的学生实例,并将名字修改。其结果与实验二相反,方法内部的赋值操作并未改变。难道引用类型又是值传递?总结
要想理解三个实验的运行结果,其实原理并不复杂。
实验一:下图表示的是,两个变量的内存情况。只有可能是两个
a
有着不同的地址,方法内部的赋值才不会改变主程序的a值。如果两者是同一内存空间,那么方法内部的修改,必定会影响主程序的a值。文章图片
实验二:下图表示的是方法内部还未赋值的时候,两个变量的内存情况。两个变量虽然有着不同的内存空间,但是存储都是Nick的地址,实际指向的是同一个地址空间。有了Nick的存储地址,当然可以方法内部去改变Nick的值。
文章图片
赋值后
文章图片
实验三:与实验二相同,在还未创建新的实例时,两者指向的都是Nick。但是在给方法内部的
std
赋值之后,实际上改变了其存放的地址,将其指向了一个新的对象Paul。文章图片
根据三个实验的结果,我们可以论证出Java采用的是值传递,只不过对于基本类型而言,传递的是一个具体的值,而对于引用类型而言传递的也是一个具体的值,只不过这个值是一个地址。而有这个地址,我们可以对地址指向的地址空间进行操作,所以会出现实验二的情况,但是如果我们对值本身进行改变赋值,两者是互不影响的。
看到一个例子说的很形象:
【Java|Java 值传递 or 引用传递()】
文章图片
推荐阅读
- 那些年,我们一起做过的 Java 课后练习题(71 - 75)
- 拉钩Java工程师高薪训练营
- JavaScript中Infinity(无穷数)的使用和注意事项
- JavaScript中集合引用类型就这么点东西
- JavaScript防抖与节流的实现与注意事项
- Java8新特性Optional类处理空值判断回避空指针异常应用
- JavaScript深入理解节流与防抖
- JavaScript实现气球打字的小游戏
- Java并发编程数据库与缓存数据一致性方案解析
- Java并发——通过ReentrantReadWriteLock理解AQS的独占模式和共享模式