java中是否存在引用传递是存在争议的,下面我将从各个角度综合分析一下java参数的传递形式
定义
1、值传递
在方法的调用过程中,实参把它的实际值传递给形参,此传递过程就是将实参的值复制一份传递到函数中,这样如果在函数中对该值(形参的值)进行了操作将不会影响实参的值。因为是直接复制,所以这种方式在传递大量数据时,运行效率会特别低下。
2、引用传递
引用传递弥补了值传递的不足,如果传递的数据量很大,直接复过去的话,会占用大量的内存空间,而引用传递就是将对象的地址值传递过去,函数接收的是原始值的首地址值。在方法的执行过程中,形参和实参的内容相同,指向同一块内存地址,也就是说操作的其实都是源数据,所以方法的执行将会影响到实际对象。
java中数据类型
基本类型:编程语言中内置的最小粒度的数据类型。它包括四大类八种类型:
- 4 种整数类型:byte、short、int、long
- 2 种浮点数类型:float、double
- 1 种字符类型:char
- 1 种布尔类型:boolean
引用类型:引用也叫句柄,引用类型,是编程语言中定义的在句柄中存放着实际内容所在地址的地址值的一种数据形式。它主要包括:
- 类
- 接口
- 数组
应用场景
【值传递】
值传递传递的是真实内容的一个副本,对副本的操作不影响原内容,也就是形参怎么变化,不会影响实参对应的内容。
public class Test
{
public static void changeStr(String str)
{
str = "welcome";
}
public static void main(String[] args)
{
String str = "1234";
changeStr(str);
System.out.println(str);
}
}
运行结果:
1234
【引用传递】
引用 也就是指向真实内容的地址值,在方法调用时,实参的地址通过方法调用被传递给相应的形参,在方法体内,形参和实参指向通愉快内存地址,对形参的操作会影响的真实内容。
public class Demo {
public static void PersonCrossTest(Person person){
System.out.println("传入的person的name:"+person.getName());
person.setName("二哈");
System.out.println("方法内重新赋值后的name:"+person.getName());
}
//测试
public static void main(String[] args) {
Person p=new Person();
p.setName("藏獒");
p.setAge(3);
PersonCrossTest(p);
System.out.println("方法执行后的name:"+p.getName());
}
}
运行结果
传入的person的name:藏獒
方法内重新赋值后的name:二哈
方法执行后的name:二哈
分歧
【代码示例】
在方面中多了person = new Person(); 这条语句,结果就发生了变化
public class Demo {
public static void PersonCrossTest(Person person){
System.out.println("传入的person的name:"+person.getName());
person = new Person();
person.setName("二哈");
System.out.println("方法内重新赋值后的name:"+person.getName());
}
//测试
public static void main(String[] args) {
Person p=new Person();
p.setName("藏獒");
p.setAge(3);
PersonCrossTest(p);
System.out.println("方法执行后的name:"+p.getName());
}
}
传入的person的name:藏獒
方法内重新赋值后的name:二哈
方法执行后的name:藏獒
可以发现,person = new Person(); 这条语句似的形参的地址再次发生了变化,分歧在于,一种思想认为:引用传递中形参实参指向同一个对象,形参的操作会改变实参对象的改变。另一种思想认为:实参传值给形参后,形参自己改变了地址,这就和引用传递无关了。何以认为,读者自己思考即可。
补充:
String是不可变类,他的赋值语句,
str = "String";
等同于引用类型的 new
person = new Person();
在参数这里的值传递和引用传递的区分,要跟深拷贝和浅拷贝进行区别和联系,因为对于对象中成员变量是值引用,使用的是浅拷贝,但是当成员变量是引用类型(对象、数组等),使用直接赋值的方式,两者还是指向同一个内存区域的,详细看:Java面试知识点(三十五)深拷贝和浅拷贝
转载:https://blog.csdn.net/qq_33945246/article/details/102465108