美文网首页
【String】substring()工作原理及在JDK6和7+

【String】substring()工作原理及在JDK6和7+

作者: 胖三斤66 | 来源:发表于2019-11-19 10:47 被阅读0次

    非原创,参考:灵魂拷问:Java 的 substring() 是如何工作的?

    1.substring() 是干嘛的?

    函数substring(int beginIndex, int endIndex)
    返回:截取给定范围的子串,介于原有字符串的起始下标 beginIndex 和结尾下标 endIndex-1 之间。
    示例

    String str = "hello world";
    String subStr = str.substring(0,5);
    System.out.println(subStr) 
    /* output:
    * hello
    */
    

    2.在JDK6和7+的实现有什么区别?

    2.1 在JDK6的实现

    源码

    String(int offset, int count, char value[]) {
        this.value = value;
        this.offset = offset;
        this.count = count;
    }
     
    public String substring(int beginIndex, int endIndex) {
        //check boundary
        return  new String(offset + beginIndex, endIndex - beginIndex, value);
    }
    

    解释:调用 substring() 的时候虽然创建了新的字符串,但字符串的值 value 仍然指向的是内存中的同一个数组,如下图所示。

    jdk1.6的substring()实现

    2.2 在JDK7+的实现

    源码

    public String(char value[], int offset, int count) {
        //check boundary
        this.value = Arrays.copyOfRange(value, offset, offset + count);
    }
     
    public String substring(int beginIndex, int endIndex) {
        //check boundary
        int subLen = endIndex - beginIndex;
        return new String(value, beginIndex, subLen);
    }
    

    解释:substring() 通过 new String() 返回了一个新的字符串对象,在创建新的对象时通过 Arrays.copyOfRange() 深度拷贝了一个新的字符数组。如下图所示

    jdk7+的substring()实现

    2.3 对比

    从源码上,JDK6 和 JDK7+ 在于 new String()String 构造函数的区别。

    JDK6 的实现

    • 优点:节省空间,因为共用一个 value 数组。
    • 缺点:容易造成内存泄漏。比如原字符串是一个很长很长的字符串,当我们调用 substring() 只截取其中很小一段子串,且后续操作只用到这个子串。但由于该子串还是引用了很长很长的字符串常量,导致这个很长很长的字符串常量无法回收,内存一直被占用着,就有可能引发内存泄露。

    总结:JDK6 的实现可谓“成也萧何,败也萧何”

    JDK7+的实现

    • 优点:避免了 JDK6 的内存泄漏问题
    • 缺点:无法像 JDK6 通过引用同一数组实现节省空间的能力

    最后,虽然 JDK6 已经基本没人使用了,但通过它可以去了解常见的内存泄漏的情况,也提醒自己避免出现这种情况。

    相关文章

      网友评论

          本文标题:【String】substring()工作原理及在JDK6和7+

          本文链接:https://www.haomeiwen.com/subject/nyfwictx.html