全网最硬核的源码分析之——String源码分析

String类在日常开发过程中使用频率非常高,但是大家真的认真了解过它么。

一:实现接口。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
  • String类被final关键字修饰,不能被继承,创建后不可修改。

  • java.io.Serializable

可以实现序列化,标记接口,用于标识序列化,未实现该接口无法被序列化。

  • Comparable

可以比较大小,这个接口只有一个compareTo(T 0)接口,用于对两个实例化对象比较大小。

  • CharSequence

String本质是个char类型数组,这个接口是一个只读的字符序列。String、StringBuilder、StringBuffer都实现了这个接口。

二:成员变量

/** The value is used for character storage. */
private final char value[];

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

可以看到,value[]是存储String的内容的,即当使用String str = “abc”;的时候,本质上,"abc"是存储在一个char类型的数组中的。

三:实现方法

再继续看String类的一些方法实现:

 */
    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);
    }

public String concat(String str) {
        int otherLen = str.length();
        if (otherLen == 0) {
            return this;
        }
        int len = value.length;
        char buf[] = Arrays.copyOf(value, len + otherLen);
        str.getChars(buf, len);
        return new String(buf, true);
    }

public String replace(char oldChar, char newChar) {
        if (oldChar != newChar) {
            int len = value.length;
            int i = -1;
            char[] val = value; /* avoid getfield opcode */

            while (++i < len) {
                if (val[i] == oldChar) {
                    break;
                }
            }
            if (i < len) {
                char buf[] = new char[len];
                for (int j = 0; j < i; j++) {
                    buf[j] = val[j];
                }
                while (i < len) {
                    char c = val[i];
                    buf[i] = (c == oldChar) ? newChar : c;
                    i++;
                }
                return new String(buf, true);
            }
        }
        return this;
    }

从上面的三个方法可以看出,无论是substring、concat还是replace操作都不是在原有的字符串上进行的,而是重新生成了一个新的字符串对象。说进行这些操作后,最原始的字符串并没有被改变。

String对象一旦被创建就是固定不变的,对String对象的任何改变都不影响到原对象,相关的任何操作都会生成新的对象。

四、总结

1.String类初始化后是不可变的(immutable)

String使用private final char value[]来实现字符串的存储,也就是说String对象创建之后,就不能再修改此对象中存储的字符串内容,就是因为如此,才说String类型是不可变的(immutable)。程序员不能对已有的不可变对象进行修改。我们自己也可以创建不可变对象,只要在接口中不提供修改数据的方法就可以。
然而,String类对象确实有编辑字符串的功能,比如replace()。这些编辑功能是通过创建一个新的对象来实现的,而不是对原有对象进行修改。比如:

s = s.replace("World", "Universe");

上面对s.replace()的调用将创建一个新的字符串"Hello Universe!",并返回该对象的引用。通过赋值,引用s将指向该新的字符串。如果没有其他引用指向原有字符串"Hello World!",原字符串对象将被垃圾回收。

如果感觉对您有帮助,希望大家可关注一下,点个赞再走,感谢您的阅读。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值