java 值传递和引用传递

什么是值传递 和 引用传递?

值传递:在调用函数时将实参复制一份给形参,在函数中修改形参不会影响实参

引用传递:在调用函数时将实参的地址直接给形参,在函数中修改形参会影响实参

值传递和引用传递的区别?

给的是实参值的备份,还是实参值。

生活举例:我家大门只有1把钥匙,朋友要我家的钥匙。

  • 值传递:我配了把备用钥匙给朋友。
  • 引用传递:我把仅有的那把钥匙给朋友。

问题一:不是说值传递形参修改不会影响实参吗?

方法A的入参是对象,方法A中修改对象的属性;方法B创建对象,调用方法A,输出对象,发现对象的属性变了;不是违反了吗?

答:见下代码。functionB中new Car并给age赋值1,调用functionA修改age为2,functionB输出car,发现age变成2。

  1. 首先:引用类型的变量的值是地址,指向堆空间的对象。functionB中的变量car的值是地址。
  2. 其次:方法调用会备份实参的值,传递给形参。functionB备份变量car的值(也就是地址),传递给functionA。
  3. 最后:functionA根据地址找到堆空间的对象,修改对象的属性。但是,functionB中的变量car的值 (地址) 没变,变的是地址指向的对象的属性。
public class ParamTest {

    public void functionA(Car car){
        car.setAge(2);
    }

    /**
     * 代码注意点:
     * Car类没有重写equals 和 hashCode方法,默认用的是Object类的方法。
     * Object类的hashCode方法返回对象在堆空间的地址的hash码。
     * 所以调用hashCode方法,一定程度上可以表示对象的地址。
     */
    public void functionB(){
        Car car = new Car("五菱宏光",1);
        System.out.println("调用A方法前地址的hash值:"+car.hashCode());
        System.out.println("调用A方法前内容:"+car);
        functionA(car);
        System.out.println("调用A方法后地址的哈希值:"+car.hashCode());
        System.out.println("调用A方法后内容:"+car);
    }

    public static void main(String[] args){
        ParamTest test = new ParamTest();
        test.functionB();
    }
}

输出结果:
调用A方法前地址的hash值:821270929
调用A方法前内容:Car{name='五菱宏光', age=1}
调用A方法后地址的哈希值:821270929
调用A方法后内容:Car{name='五菱宏光', age=2}

问题二:不是说引用类型传递的是地址吗,为什么String类型的数据作为形参并修改,调用方根据地址找到对象,发现没变?

答:见下代码。stringB中new String并赋值“abc”,调用stringA修改为“ab”,stringB输出发现还是“abc”。

  • 首先:String类的对象具有不可变性,值一旦确定就不能变。
  • 其次:String s1 = new String("abc"),先在堆空间创建对象,再在字符串常量池创建“abc”,堆空间的对象保存常量池“abc”的地址。结果:s1的值是堆空间String对象的地址,堆空间String对象存的是常量池中“abc”的地址。
  • 最后:
    1. stringA中str的值是常量池中“ab”的地址。stringA中str="ab",会先去常量池找等于“ab”的字符串,没找到就新增“ab”字符串。
    2. stringB中s1是堆空间String对象的地址,对象存的是堆空间“abc”的地址。
public class ParamTest {

    public void stringA(String str){
        str = "ab";
    }

    public void stringB(){
        String s1 = new String("abc");
        stringA(s1);
        System.out.println(s1);
    }

    public static void main(String[] args){
        ParamTest test = new ParamTest();
        test.stringB();
    }
}
输出
abc

参考文章:为什么说Java中只有值传递_程序员小灰的博客-CSDN博客_java都是值传递

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值