前言
今天有人问我Java中参数得传递是值传递,还是引用传递,还是两种都有?
我的回答是:Java中只有值传递。 当他问我为什么得时候,我说不出个所以然。最后通过查阅别人得一些间接,写下了这篇博客,如果有任何错误之处,希望大家给与指教。
为什么Java只有值传递?
JAVA中得类型分为 8 个基本类型 和 其他的引用类型。
我们首先看下面几种情况:
- 基本数据类型作为参数
public class Test {
public static void main(String[] args) {
int arg = 1;
System.out.println("main:before " + arg);
change(arg);
System.out.println("main:after " + arg);
}
public static void change(int arg){
arg = 5;
System.out.println("change: " + arg);
}
}
结果截图: 方法中的改变,并没有改变main中的值,所以肯定是值传递。
- 引用传递
第一种情况:
public class Test {
public static void main(String[] args) {
String name = "jack";
System.out.println("main:before " + name);
change(name);
System.out.println("main:after " + name);
}
public static void change(String name){
name = "tom";
System.out.println("change: " + name);
}
}
结果截图: 当传递的是String对象,在方法中进行修改不会更改main中的值。那么看下面这种情况。
第二种情况:
public class Test {
public static void main(String[] args) {
String name = "jack";
int age = 1;
Student stu = new Student(name,age);
System.out.println(stu);
change(stu);
System.out.println(stu);
}
public static void change(Student stu){
stu.setName("tom");
stu.setAge(5);
}
static class Student{
private String name;
private int age;
public Student(){
}
public Student(String name , int age){
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public String getName(){
return this.name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
}
结果截图:
从结果来看,好像stu的值好像改变了,是不是就意味着Java中存在引用传递?
其实并不是,这种情况依然是值传递!!!
我们知道 Student stu = new Student(name,age); 这段代码,首先会在堆区new 一个对象,然后stu 引用这个对象。
当我们调用change()方法的时候,其实是将引用拷贝了一份,(两个对象指向同一个引用)对于stu来说,它自己的地址才代表的实参,change()是对参数的修改,并没有影响stu的地址,而是修改了对象属性(因为修改了同一个引用,所以才会看到stu发生了改改变,但是实际上stu自身的地址并没有任何改变)。而我们混淆的原因在于,我们看见对象本身被修改了。
还是理解不了没关系,看下面的代码,我们修改change()种的代码
public static void change(Student stu){
stu = new Student("tom",5);
}
结果:
为什么?就像上面所说,传进去的参数其实不是实参,而是一个拷贝,不过是指向同一个引用,当在change()方法中,又指向另一个引用时,并不会影响stu。
“引用传递”中的“引用”二字,绝对不能简单的理解为“引用类型”中的“引用”,而应该理解为“指针”、“地址”,Java中就算是基本类型也同样拥有“地址”和“指针”。
|