substring(int beginIndex, int endIndex)在JDK6与JDK7中的实现方式不一样,理解他们的差异有助于更好的使用它们。为了简单起见,下面所说的substring()指的就是substring(int beginIndex, int endIndex)方法。

1.substring()是做什么的?

substring(int beginIndex ,int endIndex)方法返回一个子字符串,返回的是从原字符串的beginIndex到endIndex-1之间的内容。

String x = "abcdef";
x = x.substring(1,3);
System.out.println(x);

输出:

"bc"

2.当substring()被调用的时候,内部发生什么事?

你或许会认为由于x是不可变的对象,当x被x.substring(1,3)返回的结果赋值后,它将指向一个全新的字符串如下图:

然而,这个图并不完全正确,或者说并没有完全表示出java 堆中真正发生的事情。那么当调用substring()的时候到底发生的了什么事呢?JDK 6与JDK7的substring方法实现有什么不一样呢?

3.JDK6中的substring()

java中字符串是通过字符数组来支持实现的,在JDK6中,String类包含3个域,char[] value、int offset、int count。分别用于存储真实的字符数组、数组的偏移量,以及String所包含的字符的个数。

当substring()方法被调用的时候,它会创建一个新的字符串对象,但是这个字符串的值在java 堆中仍然指向的是同一个数组,这两个字符串的不同在于他们的count和offset的值。

下面是jdk6中的原代码,是简化后只包含用来说明这个问题的关键代码:

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

4.jdk6中substring()将会导致的问题

如果你有一个非常长的字符串,但是你仅仅只需要这个字符串的一小部分,这就会导致性能问题(译注:可能会造成内存泄露,这个bug很早以前就有提及),因为你需要的只是很小的部分,而这个子字符串却要包含整个字符数组,在jdk6中解决办法就是使用下面的方法,它会指向一个真正的子字符串。

x = x.substring(x, y) + ""

5.JDK7中的substring()

在JDK7中有所改进,substring()方法在堆中真正的创建了一个新的数组,当原字符数组没有被引用后就被GC回收了.因此避免了上述问题.

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

译注: 在最新的Oralce JDK 6u45中,substring的实现方式已经改进了,不过我查到openjdk的6-b14就是原来的实现方式,有兴趣的可以查查具体是哪个版改进的.

原文链接: programcreek 翻译: ImportNew.com刘志军
译文链接: http://www.importnew.com/7418.html
转载请保留原文出处、译者和译文链接。]

[转]JDK6和JDK7中的substring()方法的更多相关文章

  1. JDK6和JDK7中的substring()方法

    substring(int beginIndex, int endIndex)在JDK6与JDK7中的实现方式不一样,理解他们的差异有助于更好的使用它们.为了简单起见,下面所说的substring() ...

  2. 菜鸟译文(三)——JDK6和JDK7中substring()方法的对比

    substring(int beginIndex, int endIndex)方法在JDK6和JDK7中是不同的.了解他们的区别可以让我们更好的使用这个方法.方便起见,以下用substring() 代 ...

  3. JDK6与JDK7中String类subString()方法的区别

    1.subString()方法的作用 subString(int beginIndex, int endIndex)方法的返回的是以beginIndex开始到 endIndex-1结束的某个调用字符串 ...

  4. [译]JDK 6 and JDK 7中的subString()方法

    (说明,该文章翻译自The substring() Method in JDK 6 and JDK 7) 在JDK 6 and JDK 7中的substring(int beginIndex, int ...

  5. JDK6和JDK7中String的substring()方法及其差异

    翻译人员: 铁锚 翻译日期: 2013年11月2日 原文链接: The substring() Method in JDK 6 and JDK 7   在JDK6与JDK7这两个版本中,substri ...

  6. Java的String中的subString()方法

    方法如下: public String substring(int beginIndex, int endIndex) 第一个int为开始的索引,对应String数字中的开始位置, 第二个是截止的索引 ...

  7. substring()方法到底做了什么?不同版本的JDK中是否有区别?为什么?

      该文章是图说Java系列文章中的一篇 substring(int beginIndex, int endIndex)方法在jdk 6和jdk 7中的实现是不同的.了解他们的区别可以帮助你更好的使用 ...

  8. 二 、在 JDK 6 and JDK 7中 substring() 方法

    在JDK6 和JDK 7 里面substring(int beginIndex, int endIndex)的方法是不同的.知道这种区别会帮助你更好用它们.为了简单期间,下面用substring() ...

  9. 注意:字符串substring方法在jkd6,7,8中的差异。

    标题中的substring方法指的是字符串的substring(int beginIndex, int endIndex)方法,这个方法在jdk6,7是有差异的. substring有什么用? sub ...

随机推荐

  1. Java——FIle:

    1.读取文件夹中的文件 /** * 读取图片文件 * @param imgPath 文件所在的文件夹绝对路径 * @return * @throws FileNotFoundException */ ...

  2. windows下使用xShell远程连接virtualbox里面的linux

    第一阶段:基本安装 安装virtual box 在virtualbox里面安装xubuntu:是ubuntu+xfce桌面环境的一个linux的发行版本 在windows下安装Xmanager Ent ...

  3. Xcode:Foundation框架找不到,或者是自动提示出现问题

    问题描述:Foundation框架找不到,或者是自动提示出现问题 之前的操作:手贱,不少心把编译器里面的源码改了 处理办法:清理缓存 缓存位置:点击桌面后,选择系统菜单栏:前往—电脑—硬盘—用户—ap ...

  4. jquery的隐式类型转换

    jquery的选择器想用变量来传,然后就纠结怎么写引号的问题??? 当时脑子就犯轴了,这个我要是传变量怎么写引号啊,我要是在最外层在加一层引号就不对了,就没法识别变量了,不加反而对了 那就用conso ...

  5. 移动端 移动web屏幕适配方案 随不同宽度的屏幕而改变

    链接地址1:http://www.cnblogs.com/zjzhome/p/4802157.html 链接地址2:http://www.html-js.com/article/Mobile-term ...

  6. ToStringBuilder 学习

    一.简介与引入   1.ToStringBuilder.HashCodeBuilder.EqualsBuilder.ToStringStyle.ReflectionToStringBuilder.Co ...

  7. iOS - OC 内存管理

    1.OC 基本内存管理模型 1.1 自动垃圾收集 在 OC 2.0 中,有一种称为垃圾收集的内存管理形式.通过垃圾收集,系统能够自动监测对象是否拥有其他的对象,当程序执行需要空间的时候,不再被引用的对 ...

  8. CentOS6.4_x86_开关机查看

    1. 有时候,开机进系统的时候,就会卡在哪里,进不去系统.查看开机时 是哪个东西卡在哪里: 开机,显示进度条的时候,按 F4,就可以看到加载的具体情况了. 2. 关机的时候,有时候关闭了机: 用 CT ...

  9. [转载] iptables配置实践

    原文: http://wsgzao.github.io/post/iptables/ iptables配置实践 By wsgzao 发表于 2015-07-24 文章目录 1. 前言 2. 更新历史 ...

  10. android电池管理系统从上层的java到底层驱动的调用(转载)

    1.概述 随着移动智能设备的快速发屏,电池的续航能力在很大情况下诱导了大众消费者的购买选择,android系统对电源管理的合理与否直接影响到电池的续航能力,而电池系统作为其中的一部分,主要用于对电池状 ...