String为什么是不可变的

1..String字符串类型的数据结构

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

    /** Cache the hash code for the string */
    private int hash;  // Default to 0

   

先来了解一下final关键字的作用:

        (1)修饰变量:当修饰基本数据类型时,一旦赋予初值就不能再改变;当修饰引用类型时,初始化后不能指向一个新的对象,但是可以改变引用指向的对象内容

        (2)修饰方法:被final修饰的方法表示该方法不能被子类重写,即子类不能对final方法进行覆盖。这种设计可以用于确保某些特定的行为不会被改变。

        (3)修饰类:被final修饰的类表示该类不能被继承,即不能有子类。这种设计通常用于某些特定的类,例如String类就是一个final类,不能被继承。

不可变的原因:

        (1)字符串的本质是字符串数组,在源代码中,value使用final关键字修饰,即当value赋予初值就不能被改变。

        (2)String类使用final关键字修饰,也就是说该类不允许继承。避免出现定义一个子类继承重写String的方法,将子类设计成可变对象这种情况的出现。因为在java中,有父类引用指向子类对象这种用法,可能会导致String看起来是可变的。

2.每次修改,都会产生一个新的字符串

        每次对String对象进行修改(连接、截取等操作),都会产生一个新的字符串对象,而不是在原字符串对象上进行修改。

        这种设计是为了确保字符串对象的线程安全性和不可变性,同时也有利于字符串的缓存和重复利用。下面举一个例子来解释这个过程:

public class demo1 {
public static void main(String[] args) {
	String str="但使龙城飞将在";
	String newStr=str.substring(0,4);
	System.out.println(newStr);	
	}
}

   输出结果:

但使龙城

        在这个例子中,str字符串对象的值是“但使龙城飞将在”,调用字符串截取方法substring方法后会产生一个新的字符串对象,值为“但使龙城”,而原始的str字符串对象并没有被修改。这种不可变性体现在源码中:

public String substring(int beginIndex, int endIndex) {
    if (beginIndex < 0) {
        throw new StringIndexOutOfBoundsException(beginIndex);
    }
    if (endIndex > value.length) {
        throw new StringIndexOutOfBoundsException(endIndex);
    }
    int subLen = endIndex - beginIndex;
    if (subLen < 0) {
        throw new StringIndexOutOfBoundsException(subLen);
    }
    return ((beginIndex == 0) && (endIndex == value.length)) ? this
            : new String(value, beginIndex, subLen);
}

在源代码中,

(1)进行参数检查,确保beginIndex和endIndex在合理范围内。

(2)计算子字符串的长度subLen,即endIndex - beginIndex.

(3)如果 beginIndex 为 0 且 endIndex 为原始字符串的长度,则直接返回原始字符串本身;否则,使用 new String 创建一个新的 String 对象,其值为从 beginIndex 到 endIndex-1 的子字符串。

        

  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值