对于Java的初学者来说值传递和引用传递是一个容易混淆的概念,很多时候调用方法传入参数运行方法后的结果与自己享的不一致。那么Java到底是如何传参的呢?
简介
-
值传递:
- 在值传递中,函数接收到的是参数的值的副本,而不是参数本身。
- 当你向函数传递一个参数时,函数会创建一个新的变量,并将传递给函数的值复制到这个新变量中。
- 这意味着在函数内部对参数的修改不会影响到函数外部的原始值。
- 值传递常见于基本数据类型(如整数、浮点数、布尔值等)的传递。
-
引用传递:
- 在引用传递中,函数接收到的是参数的引用(地址)而不是参数的值的副本。
- 这意味着在函数内部对参数的修改会影响到函数外部的原始值。
- 引用传递常见于复杂数据类型(如数组、对象、类实例等)的传递。
- 多数情况下,引用传递可以节省内存空间,并且可以避免复制大量数据。
代码展示
有了基本的概念之后请看下面一段代码
public static void main(String[] args) {
int a = 10;
int b = 20;
swap(a,b);
System.out.println("main函数中a="+a);
System.out.println("main函数中b="+b);
}
public static void swap(int a,int b){
int c = a;
a = b;
b = c;
System.out.println("swap函数中a="+a);
System.out.println("swap函数中b="+b);
}
你是否认为在main方法中输出的a是20,b是10?请看输出结果。
很可惜,答案是原数值并没有交换,那么这是为什么呢?
原理分析
在Java当中一个一个方法的调用都是一个入栈的过程,main方法首先入栈,当调用了swap方法的时候swap方法入栈,此时主函数传给swap函数的a和b都会被在swap方法中拷贝出一个副本出来,副本的值的交换不影响主函数中a和b的值。
基本类型的int我们明白了之后我们看下面的一个例子。
class Student{
public String name;
public int age;
public Student(){}
public Student(String name,int age){
this.name = name;
this.age = age;
}
}
public static void main(String[] args) {
Student s1 = new Student("张三",18);
Student s2 = new Student("李四",20);
swap(s1,s2);
System.out.println(s1.name+"的年龄是"+s1.age);
System.out.println(s2.name+"的年龄是"+s2.age);
}
public static void swap(Student s1,Student s2){
int age = s1.age;
s1.age = s2.age;
s2.age = age;
}
请看结果。
结果是否与你想的一样?你可能会想,不是副本进行交换不影响主函数当中变量的值吗?为什么打印的年龄是交换的了,是不是博主拿出一个瞎打印的结果来骗你了?不不不,请看我的分析。
在Java当中我们new出来的对象是保存在堆区的,每一个对象有自己的地址,当我们在main方法中定义出s1和s2的时候,s1和s2会指向堆区当中他们new出来的对象,之后我们在调用swap方法,s1和s2的副本同样的指向到了堆区当中的s1和s2对象,那么在这个时候我们进行age的交换的时候就会影响到堆区当中的对象从而影响主方法中的对象。如果我们执行下边的代码。你觉得会改变年龄的结果吗?
public static void swap(Student s1,Student s2){
Student s = s1;
s1 = s2;
s2 = s;
}
答案是不会的,因为我们打印的是main方法中的s1和s2对象,swap方法中虽然执行了交换操作,但也仅仅是把swap方法中的s1指向了堆区当中的s2,把swap方法中的s2指向了堆区中的s1,没有对堆区对象做出影响。
结论
在Java中是按照值传递的方式,只不过参数是不同的类型可能会出现不同的结果。
希望我的解答能够为您提供帮助,喜欢的话希望给博主一个关注
标签:Java,函数,s2,中是,传递,age,swap,Student,s1 From: https://blog.csdn.net/qq_61024956/article/details/137036443