Java中String类的不可变性理解

本文深入解析了Java中String类的不可变性特性,探讨了其内部实现、创建机制,并举例说明。重点讲解了对象不可变性概念,以及为何String类设计为不可变,以及其在实际编程中的影响和更新内容,包括Java9对底层存储的调整。
摘要由CSDN通过智能技术生成


第一次写博客,好tm激动。

关于对象不可变性的描述(百度的)

如果一个对象在创建之后就不能再改变它的状态,那么这个对象是不可变的(Immutable)。不能改变状态的意思是,不能改变对象内的成员变量,包括基本数据类型变量的值不能改变,引用类型的变量不能指向其他的对象,引用类型指向的对象的状态也不能改变。(第一次写博客玩玩,你们也就随便看看啦,侵权了啥的求放过了。)

String类的概述(API的翻译)

String 类代表字符串。Java 程序中的所有字符串字面值(如 “abc” )都作为此类的实例实现。

字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。例如:

 String str = "abc";

等效于:

 char data[] = {'a', 'b', 'c'};
 String str = new String(data);

下面给出了一些如何使用字符串的更多示例:

 System.out.println("abc");
 String cde = "cde";
 System.out.println("abc" + cde);
 String c = "abc".substring(2,3);
 String d = cde.substring(1, 2);

关于String不可变性的理解

首先String类由fina修饰,代表不可被继承。其次String在实现上也就是源码里采用的是

private final char[] value;(莫名其妙的咋是文本,将就下)
数组也是引用类型的变量,所以代表它的地址值是不变的。也就是说当你创建了一个String类型的对象,它就指向了内存空间中的地址,变是不可能变的,但是不变的是地址!

String创建的问题(我扯淡的,别信)

String比较特别,可以直接赋值。

String s = "cnm";

这就是在常量池创建了一个对象。
如果你是new出来的,如:

String s = new String("abc");

其实你是创建了两个对象,一个是常量池里面的,一个是堆空间里的,然后内容一样的话堆空间的是指向常量池的。

图示(我说的对的话,就是宋红康老师教的,尚硅谷牛逼)

图示: 这是基础的解释

总结

Sting类其实就是被封装成不可变的,你看,哪怕底层char[]地址不可变,你直接通过索引调用更改内容都是可行的。

public class StringTest {
    public static void main(String[] args) {
        final char[] chars = new char[]{'a','b','c'};
        chars[0] = 'c';
        System.out.println(chars);//cbc
    }
}

综上所述
Java牛逼,sun公司牛逼,Oracle公司牛逼,尚硅谷牛逼。
是设计者把String封装成了不可变的。每次改变String的内容都会新增加一个变量。
至于为什么这样设计,好像是java设计者认为String类被创出来后一般都不会被改变,然后巴拉巴拉的决定每次改变都生成一个新的字符串运行效率高点。

更新

之前没看java9版本的api没注意,斯米马赛,java9里面把string底层改用了byte[]存储,因为用到String时通常都是a,b,c这样的字母,内存方面只需要一个字节就可以存储,当然中文什么的还是用的char[]存储,java内置有判断这样子的过程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值