在C++中我们进行参数传递的时候,往往会遇到按值传递与按引用传递的情况,但是在Java中并没有引用这个概念,在今天的写代码途中去查了一下两种语言在引用传递上的区别,在这里做一总结。
本文章只针对于Java进行分析
首先来看java中常见的数据类型Int,看看它在作为参数传递的时候是按值传递还是按引用传递
package com.zejian.test;
/**
* java中的按值调用
* @author zejian
*/
public class CallByValue {
private static int x=10;
public static void updateValue(int value){
value = 3 * value;
}
public static void main(String[] args) {
System.out.println("调用前x的值:"+x);
updateValue(x);
System.out.println("调用后x的值:"+x);
}
}
运行结果如下
调用前x的值:10
调用后x的值:10
可以发现值并没有改变,所以可以得到一个结论
Java在进行常规数据类型传参的时候(非对象类型),是采用按值传递的。

那么什么时候是按照引用传递的呢?
看下面这个例子
package com.zejian.test;
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name=name;
this.age=age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
执行类如下
package com.zejian.test;
/**
* java中的按值调用
* @author zejian
*/
public class CallByValue {
private static User user=null;
public static void updateUser(User student){
student.setName("Lishen");
student.setAge(18);
}
public static void main(String[] args) {
user = new User("zhangsan",26);
System.out.println("调用前user的值:"+user.toString());
updateUser(user);
System.out.println("调用后user的值:"+user.toString());
}
}
前面创建了User类并且创建类Set函数可以修改对象内部的值
看看运行效果
调用前user的值:User [name=zhangsan, age=26]
调用后user的值:User [name=Lishen, age=18]
在调用函数之后,原来的User发生了变换,达到了按引用传递的效果。
所以可以得出结论:
Java中对象类型的参数,进行参数传递的时候采用的是"按引用传递"。
为什么这里要用引号而不是直接写按引用传递呢?因为Java中并没有按引用传递,这里的按引用传递其实是按值传递的变式,也是按值传递的一种。
是不是觉得有点懵逼?按值就按值按引用就按引用,绕什么弯子嘛,看下面这个例子你就懂了。
package com.zejian.test;
/**
* java中的按值调用
* @author zejian
*/
public class CallByValue {
private static User user=null;
private static User stu=null;
/**
* 交换两个对象
* @param x
* @param y
*/
public static void swap(User x,User y){
User temp =x;
x=y;
y=temp;
}
public static void main(String[] args) {
user = new User("user",26);
stu = new User("stu",18);
System.out.println("调用前user的值:"+user.toString());
System.out.println("调用前stu的值:"+stu.toString());
swap(user,stu);
System.out.println("调用后user的值:"+user.toString());
System.out.println("调用后stu的值:"+stu.toString());
}
}
运行结果如下
调用前user的值:User [name=user, age=26]
调用前stu的值:User [name=stu, age=18]
调用后user的值:User [name=user, age=26]
调用后stu的值:User [name=stu, age=18]
在上述代码中,如果我们的函数是按照引用传递的,那么SWAP函数进行调用的时候,User x 与 User y应该是进行了互换的,但是并没有,所以我们可以确定,在传参的时候就是按值传递的,但是为什么回出现之前那种按引用传递的效果呢?
看下面这张图

在进行传递参数的时候,函数内部依旧是按照值传递复制了一个user类型的对象,但是与之前不同的是,这个对象指向原来的user对象的地址,所以可以理解为在函数中的原user对象的拷贝,这个符合按值传递,但由于指向同一个地址,所以对拷贝之后的User对象进行修改会修改地址中原来的值,所以就会出现按引用传递的效果了。
但是! 如果你想将这个拷贝的对象指向一个新的地址的话,那么并不会影响原来的User,它依旧在那,不离不弃~~
最后用我的一句话来总结
Java中非对象数据类型按值传递,对象数据类型按"引用传递",但是你只可以修改它的值,不可以指向新的地址!
最后的最后,附上这篇博客的转载之处,看不懂的同学可以去原博客看看Java按值传递与按引用传递
有什么不对的地方,欢迎指正!
网友评论