博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JDK6和JDK7中的substring()方法
阅读量:6594 次
发布时间:2019-06-24

本文共 1840 字,大约阅读时间需要 6 分钟。

hot3.png

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

1.substring()是做什么的?

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

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

输出:

1
"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中的原代码,是简化后只包含用来说明这个问题的关键代码:

1
2
3
4
5
6
7
8
9
10
11
//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()将会导致的问题

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

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

5.JDK7中的substring()

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

1
2
3
4
5
6
7
8
9
10
11
//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的就是原来的实现方式,有兴趣的可以查查具体是哪个版改进的.

转载于:https://my.oschina.net/songjianguo/blog/728983

你可能感兴趣的文章
HDU1879 继续畅通工程
查看>>
2019.4.27
查看>>
关于颜色(color、background)
查看>>
BOM:浏览器对象模型
查看>>
打印机彩色打印设置(将彩色打印为黑色)
查看>>
nodejs实现简易MVC
查看>>
【iOS-iap防护】验证用户付费收据!拒绝iap Cracker!!让iphone越狱用户无从下手!!!...
查看>>
ERROR! MySQL server PID file could not be found!的解决方法
查看>>
看板记录工具wekan
查看>>
【转载】CocoaPods安装和使用教程
查看>>
jquery.validation.js 表单验证
查看>>
Kettle提高输入输出数据总结
查看>>
7.16学习进度
查看>>
DS博客作业03--栈和队列
查看>>
在POM配置Maven plugin提示错误“Plugin execution not covered by lifecycle configuration”的解决方案...
查看>>
网络配置和系统管理操作
查看>>
#pragma once与 #ifndef的区别
查看>>
python之字符编码(三)
查看>>
前三次作业总结——分析与反思
查看>>
【BZOJ2117】 [2010国家集训队]Crash的旅游计划
查看>>