String类源码分析

String类源码分析

源码版本为java8

源码解析

  • 实现Serializable接口,Comparable接口,CharSequence接口
    • Serializable 接口: 可序列化对象接口 接口内无函数
    • comparable 接口: 比较器接口 内有compareTo方法
    • CharSequence: 字符序列 length,charAt,subSequence等方法
  • 属性
    • final 类型的 char数组 value
    • 序列化id
    • int hash
  • 构造方法
    • String()
    • String (String) -> 赋值value 和 hash 值
    • String (char []) -> 使用Arrays工具类复制一个数组赋值给value
    • String (char[], offset, count) -> Arrays.copyOfRange(value, offset, offset+count)
  • 常用方法
    • length() -> 返回 value.length
    • equals() -> 1.判断是否是String类型 2.是否长度相等 3.每一个字符是否相等
    • getByte() -> 直接返回value数组
    • compareTo() -> 从第0位比较两个字符的值 如果相同比较下一位 都相同则length长的大
    • indexOf(int char) -> 从第0位比较字符,相等返回位置
    • indexOf(String string) -> 双循环比较两个String的value字符数组,第一位相同的时候往后比较每一位的值是否相等 具体实现为indexOf(char[],int ,int,char[],int,int)方法
    • lastIndexOf() -> 从最后开始比较 和 indexOf 相似
    • subSting () -> 根据String的String(String, begin, end)构造方法返回新的String,需要用一个对象接收新的String对象,原有的String不可变,还是为原来的值,String 对象不可变!
    • toLowerCase() -> 对照asall码,将在大写的字母范围内的都变成小写
    • trim() -> 找到第一个不为’ '的字符和最后一个不为‘ ’的字符,假如第一位=0 最后一位 = value.length,则返回原String, 否则调用new String(Stirng,begin, end)创建一个新的String
    • intern() -> native 本地方法 和虚拟机JVM的本地方法相关
    • split() -> 单个字符截断使用subString截断,多String调用Pattern.compile(regex)然后递归

源码片段

  • byte数组转String
public String(byte ascii[], int hibyte, int offset, int count) {
    checkBounds(ascii, offset, count);
    char value[] = new char[count];
    if (hibyte == 0) { 
    for (int i = count; i-- > 0;) {
    //将每一位和0xff比较  0xff 转换成2进制为1111 1111 两个都为1则为1 其他的为0,所以只留下最后8位(一个字节)
    value[i] = (char)(ascii[i + offset] & 0xff);
    }
    }
    else {
    hibyte <<= 8; 
    for (int i = count; i-- > 0;) {
    value[i] = (char)(hibyte | (ascii[i + offset] & 0xff));
    }
    } 
    this.value = value;
    }
    public String[] split(String regex, int limit) {
        char ch = 0;
        /* 
            用一个字符隔断string
            进入循环的条件
            1. 长度为1 没有正则相关的字符
            2. 长度为2 第一个是转义字符  且非数字和字母
        */
        if (((regex.value.length == 1 &&
             ".$|()[{^?*+\\".indexOf(ch = regex.charAt(0)) == -1) ||
             (regex.length() == 2 &&
              regex.charAt(0) == '\\' &&
              (((ch = regex.charAt(1))-'0')|('9'-ch)) < 0 &&
              ((ch-'a')|('z'-ch)) < 0 &&
              ((ch-'A')|('Z'-ch)) < 0)) &&
            (ch < Character.MIN_HIGH_SURROGATE ||
             ch > Character.MAX_LOW_SURROGATE))
        {
            int off = 0;
            int next = 0;
            boolean limited = limit > 0;
            ArrayList<String> list = new ArrayList<>();
            while ((next = indexOf(ch, off)) != -1) {
                if (!limited || list.size() < limit - 1) {
                    list.add(substring(off, next));
                    off = next + 1;
                } else {    // last one
                    //assert (list.size() == limit - 1);
                    list.add(substring(off, value.length));
                    off = value.length;
                    break;
                }
            }
            // If no match was found, return this
            if (off == 0)
                return new String[]{this};
            // Add remaining segment
            if (!limited || list.size() < limit)
                list.add(substring(off, value.length));
            // Construct result
            int resultSize = list.size();
            if (limit == 0) {
                while (resultSize > 0 && list.get(resultSize - 1).length() == 0) 
{
                    resultSize--;
                }
            }
            String[] result = new String[resultSize];
            return list.subList(0, resultSize).toArray(result);
        }
        return Pattern.compile(regex).split(this, limit);
    }

心得

  • String的内容为里面的final 类型的char 数组,所以String的对象是不可变的
  • 同一个类的私有属性,不同的对象在自己的类里面的方法可以直接调用私有对象
    • eg: value = otherString.value
  • & 与字符 两个为1的时候结果才是1
  • 0xff 为16进制 转换成2进制为1111 1111,所以 & 0xff 保留8位小数
  • “>> x 右移运算符 (*2^-x) 左移同理”
  • 方法里面尽量将不符合条件的直接返回错误或者false 减少方法消耗的时间和性能
  • 重载方法相同的尽量将主要逻辑写在最复杂的方法中,逻辑代码尽量只写一份
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值