Java中的String为什么不是引用传递?

一、我们都知道Java中只有值传递,所以String也一定是值传递。

二、String是对象类型,把它当做方法形参进行值传递的时候,会拷贝其地址副本,我们在方法中对它进行修改为什么没有生效?使用StringBuffer表现出的结果为什么与String不同?

  1. 如下是String的测试代码
    在这里插入图片描述

  2. 如下是StringBuffer的测试代码
    在这里插入图片描述

三、String源码解读

  1. 我们首先看看String的几段关键代码,首先它拥有4个成员变量。
    要点001: value[]是用来保存字符的,但是它被final修饰了。
    要点002: final修饰的成员变量仅在第一次初始化时被赋值,以后不可更改
    要点003: 由于final修饰的是数组,所以value[]的地址值不可能再发生变化。它里面存储的char值依然可以改变
    在这里插入图片描述
  2. 我们再看看String中的concat方法是如何执行的
    在这里插入图片描述
  3. 如果你能修改到String中的value[],我们采用反射的方式对value进行修改,这样外层的s1才会变化!
    在这里插入图片描述
  4. String的结论:String没有提供可以修改其成员变量value[]的API,所以我们把s1当做形参传入方法时,只要不人为改变它成员变量value[]的值,方法执行完之后对外层的s1不会产生任何影响!
  5. 注意:我们熟知的+运算符,在Java中只有String重写了这个运算符,它的底层走的是AbstractStringBuilder的append方法!与StringBuffer的append方法是一样的。

四、StringBuffer源码解读

  1. 先看成员变量,它继承自AbstractStringBuilder
    在这里插入图片描述

  2. 再看看AbstractStringBuilder的成员变量有哪些
    在这里插入图片描述

  3. 然后看看关键的append方法,先执行ensureCapacityInternal,然后执行str.getChars 方法。
    在这里插入图片描述

  4. 我们先看ensureCapacityInternal方法,它又调用了Arrays.copyOf方法
    在这里插入图片描述

  5. 看看Arrays.copyOf 方法在干嘛
    在这里插入图片描述

  6. ensureCapacityInternal执行完之后,下一步就是执行str.getChars方法了
    在这里插入图片描述

  7. StringBuffer总结:value、count没有被final修饰,所以可以被更改。append方法就是修改了value以及count的值,所以把StringBuffer当做形参传入方法,执行changeStr后,外层的StringBuffer值也会受到影响!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值