java值传递和引用传递区别和易错点

先看一个值传递案例

    @Test
    public void fun1(){
        String name = "name1";
        fun2(name);
        System.out.println(name);
    }

    public void fun2(String name){
        name = "name2";
    }

粗看代码,快速通读下来,name变量被传递给fun2方法,值应该被修改为 “name2”,然后fun1方法中应该打印出 “name2” 才对… 但是打印的是 name1

回头细想,原因很简单,因为在java中参数传递分为值传递和引用传递,说白了fun2(name)传递给fun2方法,本质等价于 fun2(“name1”),将值本身传递了过去,所以fun2方法中的name仅仅是该方法的一个局部变量,跟fun1中的name变量毫无关系。

那么java中哪些是值传递哪些是引用传递呢?

基本类型包括:byte,short,int,long,char,float,double,Boolean,returnAddress
引用类型包括:类类型,接口类型和数组。
需要注意特殊类型 String Integer Double 等几个基本类型的包装类,他们都是immutable类型,他们也是值传递

然后再看一个引用传递案例

    @Test
    public void fun1(){
        StringBuffer sb1 = new StringBuffer("name1");
        fun2(sb1);
        System.out.println(sb1);
    }

    public void fun2(StringBuffer sb){
        StringBuffer sb2 = new StringBuffer("name2");
        sb = sb2;
    }

现在的StringBuffer对象是妥妥的引用对象,传递的也是引用,而非值本身,所以打印出来应该是 “name2”
呵呵… 打印结果是 “name1”
What FK? Are you kidding me ?

回头再捋捋思路,sb1传递给fun2方法,这里肯定是引用传递,不用怀疑!!!
那细看发现,问题只有发生在 sb = sb2 语句了,sb2把自己的引用值赋值给了sb,在fun2方法中,sb对象确实是指向了sb2所在的堆地址,且值为"name2",那为什么回到fun1方法中,sb1的值还是"name1"呢?

我们抽象理解~~

案例2和案例1本质是一样的,什么所谓的值传递和引用传递,本质我们都可以理解为值传递
只不过案例1中传递的值是 “值本身’name1’(有点绕~~)”,案例2中传递的值是一个引用值,是栈中的一个值, 比如 “StringBuffer@254”,不管是案例1中的"name1" 还是案例2中的 “StringBuffer@254”,它们都是一个局部变量,都在fun1中才有效(局部变量的作用域决定的),所以不能在fun2中修改一个另一个方法中的局部变量
也就是案例1中的fun2方法 传递的参数"name1" 跟 fun1 中的变量 name 没有关系
同理:案例2中的fun2方法 传递的参数"StringBuffer@254" 跟 fun1 中的变量 sb1 没有关系
唯一的区别是一个是真实值,一个是栈中的引用值
如果想要修改引用中的值需要修改引用指向堆中的值,代码如下:

    @Test
    public void fun1(){
        StringBuffer sb1 = new StringBuffer("name1");
        fun2(sb1);
        System.out.println(sb1);
    }

    public void fun2(StringBuffer sb){
        sb.delete(0, sb.toString().length());
        sb.append("name2");
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值