今天终于有时间认认真真的梳理下这个问题了。
以前总听说方法参数传递有两种方式:值传递和引用传递。
值传递:很好理解就是把基本的数据类型的数据传递给一个新方法,供新方法使用,无论怎么使用都是不会影响原来的值的,因为这是把值的副本传递过去。
引用传递:顾名思义跟值传递的差别就是,把对象的引用传递过去,供方法使用,既然引用都传递过去了,那肯定是可以随意修改这个对象的值。
接下来。我详细说一下这个引用传递,因为它在Java程序中真的很神奇,很容易混乱。
首先建一个Demo实例
@Data
public class Demo {
private String url;
}
再建一个方法
public class Main {
public static void main(String[] args) {
Demo demo = new Demo(); // 这里是我们要传递的参数
demo.setUrl("www.bing.com");
System.out.println("执行方法之前的参数:" + demo);
hello(demo);
System.out.println("执行方法之后的参数:" + demo);
}
/**
* 方法
* @param demo
*/
public static void hello(Demo demo) {
demo.setUrl("www.baidu.com");
System.out.println("方法内参数:" + demo);
}
}
通过结果我们发现,hello方法成功修改了我们传过来的demo参数的值。那我们可能就会说这不是引用传递吗,把参数原来的值都改变了, 值传递是改变不了原来的值的。
是的,这就是Java这个值传递的奇妙地方。接下来我们再看一个例子。
public class Main {
public static void main(String[] args) {
Demo demo = new Demo(); // 这里是我们要传递的参数
demo.setUrl("www.bing.com");
System.out.println("执行方法之前的参数:" + demo);
hello(demo);
System.out.println("执行方法之后的参数:" + demo);
}
/**
* 方法
* @param demo
*/
public static void hello(Demo demo) {
demo = null; // 这里我们直接把参数变为null
// demo.setUrl("www.baidu.com");
System.out.println("方法内参数:" + demo);
}
}
看接口发现,我们虽然把参数在方法中设置为了null,但是只有在方法中输出是null。当回到原来主函数时,这个参数还是原来的值,所有就可以确定,Java的这种参数传递,其实还是值传递。
结论
在Java中,虽然对于对象类型参数实际上是传递对象的引用,但仍然被称为值传递的原因是因为传递的是引用的副本,而不是原始的引用本身。在Java中,当你将一个对象的引用作为参数传递给方法时,实际上是将引用的副本传递给了方法。
这意味着在方法内部对参数的修改会影响原始变量所引用的对象。但是,如果在方法内部重新为参数赋新的对象引用,原始变量并不会改变,因为这只是修改了参数副本中保存的引用,而不是原始引用本身。
因此,虽然Java中对于对象类型参数是传递引用的方式,但是本质上仍然是按值传递的逻辑。这便是为什么虽然看起来像引用传递,实际上被称为值传递的原因。