优秀的编程知识分享平台

网站首页 > 技术文章 正文

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

nanyue 2024-10-22 13:12:28 技术文章 5 ℃

观点: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)

最近发表
标签列表