国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

新版Java為什么要修改substring的實現

2019-11-06 07:47:07
字體:
來源:轉載
供稿:網友

“參考這位大神的”

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更加健壯,卻犧牲了性能 。孰優孰劣,無從評判~~


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 荔浦县| 治县。| 嘉祥县| 桐城市| 黎川县| 嵊州市| 湟中县| 三台县| 娱乐| 即墨市| 东平县| 沾益县| 万山特区| 泊头市| 大兴区| 同仁县| 铜鼓县| 沧州市| 吉水县| 通渭县| 萍乡市| 重庆市| 黔西| 博客| 湄潭县| 孝义市| 尤溪县| 哈密市| 子长县| 莎车县| 隆安县| 华宁县| 蒙城县| 安泽县| 临夏市| 运城市| 长兴县| 大同市| 大荔县| 广州市| 昆明市|