如何通过不改变引用的指向来修改内容

如何通过不改变引用的指向来修改内容

案例来源于bilibili,如有侵权,请告知删除!谢谢~


String str = new String("abc")在不改变引用指向的前提下输出“abcd”

public class No1 {
    public static void main(String[] args) throws Exception{
    String str = new String("abc");
    .....
    System.out.println(str); //abcd
}

有可能有人会想到通过StringBuilder中的append()方法以追加的方法实现;

StringBuilder stringBuilder = new StringBuilder(str)
stringBuilder.append("d");
System.out.println(str);//abc
System.out.println(stringBuilder); //abcd

通过代码实现过后,str输出任为abc,其实StringBuilder生成了一个新的stringBuilder对象,所以append()方法操作的也是stringBuilder对象,并不是我们想要的str;


还有的小伙伴可能会想到利用StringAPI中的replace来实现,

String replace = str.replace("abc","abcd");

然而,String 声明的是不可变的对象,每次操作都会生成新的 String对象,然后将指针指向新的String对象;

而且调用replace()方法,底层会生成一个StringBuffer对象,然后再对StringBuffer对象进行操作并返回;


其实,我们只要通过String源码可以看到,它是通过参数赋值给value属性,value为一个char[]数组,

即可通过反射来获取value字段,将字段值直接修改为abcd即可:

public class No1 {
    public static void main(String[] args) throws Exception{

        String str = new String("abc");
        
        //通过反射拿到str里面的value字段
        Field value = str.getClass().getDeclaredField("value");
        //修改权限为true
        value.setAccessible(true);
        //将abc直接修改为abcd并转换为字符数组
        value.set(str,"abcd".toCharArray());

        System.out.println(str);
    }

代码解析:

setAccessible()方法不属于Field,它属于AccessibleObject,
Field通过extends AccessibleObject来获得setAccessible()方法;

getDeclaredField("value"):
java.lang.Class类的getDeclaredField()方法用于获取此类的指定字段。该方法以Field对象的形式返回此类的指定字段。
    
setAccessible(true):
该方式是用来设置获取权限的。
如果 accessible 标志被设置为true,那么反射对象在使用的时候,不会去检查Java语言权限控制(private之类的);
如果设置为false,反射对象在使用的时候,会检查Java语言权限控制。
需要注意的是,设置为true会引起安全隐患。

String底层源码解析:

public String(String original) {
     this.value = original.value;
     this.hash = original.hash;
 }
// 调用String类的构造方法,通过源码可以看到,它是把传进去的值赋值给value属性
 public final class String
         implements java.io.Serializable, Comparable<java.lang.String>, CharSequenc
     /** The value is used for character storage. */
     private final char value[];
     ......
// value属性为一个char数组

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

波 多

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值