新版Java为什么要修改substring的实现
来源:互联网 发布:linux用cp复制文件 编辑:程序博客网 时间:2024/06/08 15:35
“参考这位大神的”
1.8版本的substring
// JDK1.7之后的substringpublic String substring(int beginIndex) { if(beginIndex<0) { throw new StringIndexOutOfBoundsException(beginIndex); } int subLen = this.value.length - beginIndex; if(subLen < 0) { throw new StringIndexOutOfBoundsException(subLen); } return (beginIndex == 0)?this:new String(**value**,beginIndex,subLen);}public String(char value[], int offset, int count) { if(offset < 0) { throw new StringIndexOutOfBoundsException(offset); } if(count <= 0) { if(count < 0) { throw new StringIndexOutOfBoundsExcetpion(count); } if(offset <= value.length) { this.**value** = "".**value**; return; } } if(offset > value.length - count) { throw new StringIndexOutOfBoundsException(offset + count); } this.**value** = Arrays.copyOfRange(value, offset, offset + count);}
value:String私有的char[ ] value
满足所有的条件时,substring调用了一个构造器,在这个构造器里直接拷贝数组,赋值给自己的私有变量 (外部无法访问),从而创建一个新的字符串(String创建字符串,是使用char[ ]) 。
“修改后的substring的效率变低了,并且占用了更多的内存,无论是从时间上还是空间上都比不上原有的实现”
//JDK1.7之前的substringpublic String substring(int beginIndex) { //省略判断,按理想条件走 return ((beginIndex == 0) && (endIndex == count)) ? this : new String(offset + beginIndex, endIndex - beginIndex,value);}// Package private constructor which shares value array for speed.String(int offset, int count, char value[]) { this.value = value; this.offset = offset; this.count = count;}//通过复用数组value,省去了数组拷贝的开销,仅通过3个赋值语句就创建了一个新的字符串对象
改变前: 性能好,效率高
改变后: “掩盖了优点”
那为什么要修改substring呢?为什么要牺牲其性能呢?
因为安全吗?复用数组有安全隐患吗?
旧版JDK:创建一个String对象,通过复制参数内部的数组(this.value=value)实现 。但不会有安全问题:比方说一个字符数组arr,原来是{‘h’,’e’,’l’,’l’,’o’},作为参数传给了String的构造方法,创建了一个String对象;当改变arr的内容时,创建的那个String对象没有变化(因为复制是使用的String私有的char[ ],外部无法访问)。
arr=new arr[]{'h','e','l','l','o'};str = new String(0, arr.length, arr) // 顺序和新版的不一样System.out.print(str); // helloarr[0]='A';System.out.print(str); // hello 木有改变
新版JDK:创建一个String对象,通过Arrays.copyOf方法实现 。更不会有安全问题了,来一个参数就创建一个新的String对象,即使两个参数一模一样,创建出来的对象也不相等(==)。
木有安全问题,那为什么要改变呢? 我查了一下2011年互联网发生了啥事,好多 。
因为旧版的可能存在内存泄漏的问题 。 从网络上抓个东西(A),假设100个字节长度,将A变为String对象(B),只截取其中的10个字节长度(C) 。问题来了,假设GC把A清理走了,但B还保留着A的100个字节长度的东西,导致内存泄漏 (和内存溢出的区别,参看别人的总结不让转载的,链接过去不知有没有问题啊?) 。
新版的可以把字符串对象和内部数组一起回收,更加健壮!!
总结
旧版的substring性能好,但在某些情况下内存泄漏是个很严重的问题;新版的substring更加健壮,却牺牲了性能 。孰优孰劣,无从评判~~
- 新版Java为什么要修改substring的实现
- java字符串subString的实现
- 新版linux内核对nat的修改
- 对于新版Cocoapods文件写法的修改
- substring的实现
- Android和Java中String.substring的不同实现
- oracle使用substr instr实现类似于java substring的功能
- java的subString方法
- java 的 substring
- Java的subString
- Java String的substring
- 【Java】substring的用法
- Java substring的使用
- java的substring()
- JAVA substring的用法
- 为什么要修改mssql的端口
- 新版Qq为什么不受欢迎?
- 为什么Hadoop是用Java实现的?
- STL的应用
- 剑指Offer:二叉树的镜像
- php实现签到功能
- Linux 下 安装最新 Python2.X
- 该屎的Mysql乱码
- 新版Java为什么要修改substring的实现
- LocalBroadcast详解及源码分析
- 微信小程序版豆瓣同城
- tomcat 配置数据源
- 笛卡尔积
- Leetcode 241. Different Ways to Add Parentheses
- 取数字问题2-动规
- 【AngularJS】自定义过滤器
- 补充装饰器