String 类

String不可变的原因:底层字符数组value被private和final修饰,private保证value不能被外界访问,所以我们不能直接通过字符串修改他的value值,final修饰表示不能修改value的指向,但是可以修改数组内部的值,不过String类内部所有对String操作的方法,也都并没有去修改他的内部值。总结就是:我们外部不能修改,它内部可以修改数组元素但是也没有提供修改这种方法。

 1.继承体系

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {

  String类被final修饰,所以不能有子类继承该类,String类实现了三个接口,其中Comparable<String>接口中只有一个抽象方法:

 public int compareTo(T o);

2.成员变量

private final char value[];

        从这里可以看出,String类的底层就是一个char数组。 

3.常用方法源码分析

        3.1重写的compareTo(String anotherString)方法:

public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = anotherString.value;

        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }

        该方法的作用是将当前字符串和传入的字符串比较字典顺序,分析源码可知:

        该方法是从两个字符串的第一个字符开始比较对应的ASCII值,如果不相等,则返回他们的差值,while循环比较完后,如果都相等,则返回他们的长度之差。例:

        String s1="ab";
        String s2="cd";
        String s3="abcde";
        int res1=s1.compareTo(s2); //返回第一个字符的ASCII差值 -2
        int res2=s1.compareTo(s3); //返回长度之差 -3
        System.out.println(res1);
        System.out.println(res2);

        返回值:

                正整数:参数字符串在此字符串前面

                0:两字符串相等

                负正整数:参数字符串在此字符串后面

      3.2 to CharArray()

 public char[] toCharArray() {
        // Cannot use Arrays.copyOf because of class initialization order issues
        char result[] = new char[value.length];
        System.arraycopy(value, 0, result, 0, value.length);
        return result;
    }

        源码中的System.arraycopy是一个复制数组的方法

        System.arraycopy(源数组, 源数组开始下标, 目标数组, 目标数组开始下标, 要复制的长度);   

该方法是返回一个与当前字符串对应的字符数组元素相同的字符数组,但是并不是直接返回的底层value数组。因为如果直接返回value数组,则可以修改字符串的值。

        注意:虽然value被final修饰,但是value是数组,是引用数据类型,被final修饰的引用数据类型只是引用的对象不能改变,但是对象里面的属性是可以改变的。

        3.3 charAt(index)

 public char charAt(int index) {
        if ((index < 0) || (index >= value.length)) {
            throw new StringIndexOutOfBoundsException(index);
        }
        return value[index];
    }

        该方法返回字符串中对应下标的字符,下标从0开始,因为底层就是一个字符数组,字符串的遍历就得依靠该方法。

        3.4 concat(String s)

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 static char[] copyOf(char[] original, int newLength) {
        char[] copy = new char[newLength];
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }
void getChars(char dst[], int dstBegin) {
        System.arraycopy(value, 0, dst, dstBegin, value.length);
    }

该方法的作用是拼接字符串,如:

"hello".concat("world) 的返回值是"helloworld".

源码中可以看出,Arrays.copyOf和String里面的getChars底层都是调用的System.arraycopy这个方法,buf数组相当于是新new出来的copy数组,该数组的长度是本字符串和参数字符串的长度之和

copyOf方法将本字符串复制到了新字符数组buf的前面,getChars方法将参数字符串复制到了buf的后面,实现了拼接,通过构造方法返回一个新的字符串对象,也就是拼接好的字符串对象。

3.5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值