专业的JAVA编程教程与资源

网站首页 > java教程 正文

[微知识点]一:String的subString方法详解

temp10 2024-10-01 22:30:10 java教程 10 ℃ 0 评论

本系列是一些Java中的小知识点荟萃,通过这些小知识点其实可以管中窥豹,一滴水中见世界。

1. SubString的作用是截取字符串并返回内容,示例如下:

[微知识点]一:String的subString方法详解

String x = "abcdef";

x = x.subString(1,3);

System.out.println(x);

输出结果为:

bc

2. Java Heap中String对象发生了什么?

众所周知,String对象是不可变的,所以返回的x是重新赋值之后的值,初步看Java Heap中subString的操作会发生这种变化:

这幅图仅仅从表面上展示了Java heap中的变化,并不深入,下面我们深入研究一下隐藏在这幅图之后的故事。

3. String对象源代码

想清楚的搞懂subString发生了什么,我们需要求助Sting的源代码。我们知道String类包含三个变量:

char value[], //用来存储string值的char数组

int offset, //用来标记value数组的偏移量,从第几个字符开始算是这个String的开始

int count //记录String对象长度

所以x在内存中的结构是这样的:

开始的时候,count=6 ,offset=0

4.SubString的时候发生了什么?

SubString 方法在Jdk6和Jdk7中实现是不一样的,在Jdk 6中的实现如下:

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

}

java heap中的变化如下图,可见,虽然x是新的对象,但是value数组还是原来的,这样带来一个问题就是如果在比较特殊的情况下,String原始对象比较长,但是截取后只用到很短的部分,会导致java 虚拟机无法回收,任然占用较多的内容:

而在Jdk7中修正了这个问题,改变了实现,会重新copy一个数组:

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

}

在java heap中如下:

通过源代码我们可以看出,这个改变是在String 的一个构造器中改变的,那么为什么Jdk6 和 Jdk7 会有这样的区别呢,且等下回再讲。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表