String真的不可变吗?

String不变表现形式

 		String str = "ABCabc";
        System.out.println("str="+str);
        str = "123456";
        System.out.println("str="+str);

打印结果

str=ABCabc
str=123456

首先创建一个String对象str,然后让s的值为“ABCabc”, 然后又让s的值为“123456”。 从打印结果可以看出,s的值确实改变了。那么怎么还说String对象是不可变的呢? 其实这里存在一个误区: str只是一个String对象的引用,并不是对象本身。对象在内存中是一块内存区,成员变量越多,这块内存区占的空间越大。引用只是一个4字节的数据,里面存放了它所指向的对象的地址,通过这个地址可以访问对象。 也就是说,str只是一个引用,它指向了一个具体的对象,当str=“123456”; 这句代码执行过之后,又创建了一个新的对象“123456”, 而引用str重新指向了这个新的对象,原来的对象“ABCabc”还在内存中存在,并没有改变。

内存结构:
在这里插入图片描述

String为什么不可变?

查看源码

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

通过查看源码我们发现String底层的是final修饰的char[]数组。

String真的不可变吗?

我们可以通过反射改变其值:

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

        //创建字符串"Hello World", 并赋给引用s
        String s = "Hello World";

        System.out.println("s = " + s); //Hello World

        //获取String类中的value字段
        Field valueFieldOfString = String.class.getDeclaredField("value");

        //改变value属性的访问权限
        valueFieldOfString.setAccessible(true);

        //获取s对象上的value属性的值
        char[] value = (char[]) valueFieldOfString.get(s);

        //改变value所引用的数组中的第5个字符
        value[5] = '_';

        System.out.println("s = " + s);  //Hello_World
    }

结果

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值