JAVA 是值传递还是引用传递

本文详细探讨了Java中的参数传递机制,虽然Java总是进行值传递,但对基本类型和引用类型表现不同。对于基本类型,值传递拷贝变量的值,函数内部的修改不会影响原始值。而对于引用类型,传递的是对象引用的副本,改变引用指向的内容会影响到原始对象。通过数组和对象示例,解释了这种现象,并强调了Java中并没有真正的引用传递。
摘要由CSDN通过智能技术生成

JAVA 是值传递还是引用传递 傻傻分不清楚?

  • 值传递:在调用函数的时候,把真实的实际参数传递给形式参数的时候,传递给函数的并不是实际参数本身,而是对实际参数的拷贝。所以在函数里面操作参数改变的是形参的数值,而实参的值并不会受到影响。

  • 引用传递:在调用函数的时候,把真实的实际参数传递给形式参数的时候,传递给函数的就是实际参数本身,在函数里面操作参数就是对实际参数的改变。

 public static void swap(int a, int b) { 
     int temp = a;
     a = b; 
     b = temp; 
     System.out.println("a = " + a); 
     System.out.println("b = " + b); 
 }
public static void main(String[] args) { 
    int num1 = 10;                               
    int num2 = 20; 
    swap(num1, num2); 
    System.out.println("num1 = " + num1);// num1=10		
    System.out.println("num2 = " + num2);// num2=20
}

对java而言,它只有值传递。

但对于下面两个引用类型的参数传递,有些人会感到疑惑?

public static void main(String[] args) { 
    int[] arr = { 1, 2, 3, 4, 5 }; 
    System.out.println(arr[0]); 
    change(arr); 
    System.out.println(arr[0]); 
}
public static void change(int[] array) { 
    array[0] = 0; 
}
//结果为  arr={0,2,3,4,5}  ,不是说好不变吗,怎么又变了?
    public static void swap(Student x, Student y) {

        Student temp = x;
        x = y;
        y = temp;
        System.out.println("x:" + x.getName());
        System.out.println("y:" + y.getName());
        //System.out.println(x.hashCode());//2222222
        //System.out.println(y.hashCode());//1111111
       	// y.setName("111111aaaaaa");

    }
    public static void main(String[] args) {
        Student s1=new Student("gg1");
        Student s2=new Student("gg2");
       // System.out.println(s1.hashCode());//1111111
       // System.out.println(s2.hashCode());//2222222
        swap(s1,s2);
        System.out.println("s1:" + s1.getName());
        System.out.println("s2:" + s2.getName());
    }
//main 运行结果如下  s1和s2引用对象没有发生改变
x:gg2
y:gg1
s1:gg1
s2:gg2
    
//但如果把 10行加入其中 运行结果为   s1和s2引用对象的属性name确实发生了改变
x:gg2
y:gg1    
s1:111111aaaaaa
s2:gg2

通过函数调用,数组内容的改变和对象属性的改变,难道不是代表是引用传递吗,把实际参数地址传给了形参吗?

实际上,还是值传递。只是大家对Java中的基本类型和引用类型理解还是不深。

  • 基本数据类型的值传递 好理解,实参的值放到了栈中,在函数调用的时候,如定义的swap(int a,int b)函数,输入x,y。使用swap(x,y)。a拷贝了x,是x的一个副本,后面在函数内对a的修改并不会对x进行影响。
  • 引用数据类型的值传递过程是:例如上面定义一个swap(Student x, Student y),输入s1,s2。调用swap(s1,s2)。你们看它们的hasCode就知道了,实际上 ,s1,s2的地址丝毫没变。引用对象拷贝复制的是在栈中的一个地址。这个地址是标记引用对象在堆中对象内容(属性)。所以,对于引用类型而言,值传递 拷贝复制地址使得形参和实参的地址一样,该地址指向的堆内容一样。如果形参改变了指向堆内容信息(类的属性)如 y.setName(“111111aaaaaa”),实参地址指向堆内容信息的内容也会发生改变

请添加图片描述
在这里插入图片描述

总结

  • 对于基本类型值传递是 对数值的拷贝 ,形参改变不影响实参。
  • 对于引用数据类型值传递的是引用对象地址的拷贝,但不能让一个引用对象引用新的另一个引用对象。如上,s1,s2 在进行swap函数的前后,s1和s2的地址不变。 但能通过值传递改变 一个引用对象的内容(属性)如上 arr[]={1,2,3,4,5} 进行change函数后 实际变成了arr=[0,2,3,4,5]。 s1.name 通过swap 变成 111111aaaaaa。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值