主页 > 科技

【Java】中只有值传递,没有引用传递!

时间:2020-01-19 来源:果妈的小确幸

观点:Java没有引用传递,只有值传递

Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本。指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。

基本概念

  • 实参:实际参数,是提前准备好并赋值完成的变量。分配到栈上。如果是基本类型直接分配到栈上,如果是引用类型,栈上分配引用空间存储指向堆上分配的对象本身的指针。String等基本类型的封装类型比较特殊,后续讨论。
  • 形参:形式参数,方法调用时在栈上分配的实参的拷贝。
  • 值传递:方法调用时,实际参数把它的值传递给对应的形式参数,形参接收的是原始值的一个拷贝,此时内存中存在两个相等的变量
  • 引用传递:方法调用时将实参的地址传递给对应的形参,实参和形参指向相同的内容

Java数据有两个类型

  • 基本类型
  • 引用类型

基本类型


public class Test {
public static void main(String[] args) {
int value = 100;
change(value);
System.out.println("outer: " + value);
}

static void change(int value) {
value = 200;
System.out.println("inner: " + value);
}

}

结果输出:

inner: 200
outer: 100

方法修改的只是形式参数,对实际参数没有作用。方法调用结束后形式参数随着栈帧回收。

引用类型

引用类型传递时,传递的是引用的值,从这个角度来讲还是值传递。如果是引用传递的话,传递的应该是引用的地址,而不是引用的值。

 
public class Test {
public static void main(String[] args) {
Person person = new Person();
person.setAge(17);
person.setName("Tom");
change(person);

System.out.println("outer: " + person.getAge());

}

static void change(Person value) {
value.setAge(18);
System.out.println("inner: " + value.getAge());
}

static class Person {
private String name;
private Integer age;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}
}

}

结果输出:

inner: 18
outer: 18

方法修改的是引用所指向的数据空间的数据,所以方法外部也能看到修改的结果。

基本类型的数组也是对象,所以int[] 传递的也是对象应用的值。


public class Test {
public static void main(String[] args) {
int[] intArray = new int[10];
change(intArray);

System.out.println("outer: " + intArray[0]);

}
static void change(int[] value) {
value[0] = 200;
System.out.println("inner: " + value[0]);
}


}

运行结果:

inner: 200
outer: 200

如果对引用类型的传递稍作修改

 static void change(Person value) {
value = new Person();
value.setAge(18);
System.out.println("inner: " + value.getAge());
}

运行结果:

inner: 18
outer: 17

同理String,Integer等类型的封装类型为final类型,对数据的修改操作实际上是创建了一个新的对象


public class Test {
public static void main(String[] args) {
String value = "123";
change(value);

System.out.println("outer: " + value);

}

static void change(String value) {
value = "abc";
System.out.println("inner: " + value);
}
}

运行结果:

inner: abc
outer: 123

至于是值传递和引用传递大家有什么看法,欢迎大家评论区讨论

(引用自CSDN作者:charmsongo,guhanjie)