摘要:的不可變性眾所周知,是常量,不可變,這一點很重要。那中,包裝類的一個特質就是值操作時體現對應的基本類型的特質。同樣的,等這些包裝類和在這種情況下的表現是相同的。那么無論你對傳入參數做了什么操作,都不會影響原來的值。
1. String的不可變性
眾所周知,String是常量,不可變,這一點很重要。
其底層的實現是char[]:
/** The value is used for character storage. */ private final char value[];
而且,它是final的。
看兩個構造函數:
/** * Initializes a newly created {@code String} object so that it represents * the same sequence of characters as the argument; in other words, the * newly created string is a copy of the argument string. Unless an * explicit copy of {@code original} is needed, use of this constructor is * unnecessary since Strings are immutable. * * @param original * A {@code String} */ public String(String original) { this.value = original.value; this.hash = original.hash; } /** * Allocates a new {@code String} so that it represents the sequence of * characters currently contained in the character array argument. The * contents of the character array are copied; subsequent modification of * the character array does not affect the newly created string. * * @param value * The initial value of the string */ public String(char value[]) { this.value = Arrays.copyOf(value, value.length); }
其內部的很多方法,也是會新生成一個char[]來構造一個新的String對象返回。
例如replace:
/** * Returns a new string resulting from replacing all occurrences of *oldChar
in this string withnewChar
. */ public String replace(char oldChar, char newChar) { if (oldChar != newChar) { int len = value.length; int i = -1; char[] val = value; /* avoid getfield opcode */ while (++i < len) { if (val[i] == oldChar) { break; } } if (i < len) { char buf[] = new char[len]; for (int j = 0; j < i; j++) { buf[j] = val[j]; } while (i < len) { char c = val[i]; buf[i] = (c == oldChar) ? newChar : c; i++; } return new String(buf, true); } } return this; }
doc中寫的很明白,這個方法,會新生成一個String對象返回。
所以類似
str = str.replace("a","b"); str = str.substring(2); str = str.toLowerCase();
都會生成新的對象。原來的對象還是存在的,只是沒有引用指向它,等待被垃圾回收。
2.傳遞String類型參數看一個例子:
public class StringTest { public static void main(String[] args) { StringTest stringTest = new StringTest(); String string = "abc"; stringTest.replace(string); System.out.println(string); Integer i = 1; stringTest.add(i); System.out.println(i); } public void replace(String string) { string = string.replace("a", "b"); string = string.toUpperCase(); System.out.println("inner:" + string); } public void add(Integer integer) { integer++; System.out.println("inner:" + integer); } }
Stirng內部實現時,是用char[] 來存儲字符串的,所以String相當于char[]的包裝類。那java中,包裝類的一個特質就是值操作時體現對應的基本類型的特質。同樣的,Integer、Float等這些包裝類和String在這種情況下的表現是相同的。
分析一下,主要是還是由于包裝類內部實現方式導致的。
包裝類內部存儲結構是final的原生類型,或原生類型數組,是不可變的。之后所做的操作都會新生成一個對象來返回。那么無論你對傳入參數做了什么操作,都不會影響原來的值。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/65679.html
摘要:隱式類型轉換類型轉類型先定義一個類型的變量只要類型跟類型還是類型用號,其他類型都會被轉為字符串輸出結果字符串類型轉類型或者類型定義類型的變量與類型的變量前端從測試結果可以看出,類型在跟數字類型做乘除減運算時,得到的是數字類型的值,但是類型必 隱式類型轉換 number類型轉string類型 //先定義一個number類型的變量 //只要string類型跟boolean類型還是numbe...
摘要:關于如何限速,有兩個比較出名的算法,漏桶算法與令牌桶算法,這里對其簡單介紹一下,最后再實踐在我發郵件的中以下是發送郵件的,已限制為一分鐘兩次,你可以通過修改進行試驗。 前段時間,我使用了 jwt 來實現郵箱驗證碼的校驗與用戶認證與登錄,還特別寫了一篇文章作為總結。 在那篇文章中,提到了一個點,如何限速。 在短信驗證碼和郵箱驗證碼,如果不限速,被惡意攻擊造成大量的 QPS,不僅拖垮了服務...
摘要:為了提高程序運行的效率,在軟件發布后,檢查默認是被關閉的。注意不能保證原子性,不能代替,且其會阻止編譯器對代碼的優化。以下方法用來判斷一個字符串中是否包含中文字符。 前言 面試中對于技術職位,一般分筆試與面談,如果面試官的一些小問題你可以立馬找到對應的知識點擴展開來,那么這就是你的優勢,本系列將講述一些java面試中的事,不會很詳細,但是應該比較全面吧。 主要內容 assert有什么作...
摘要:小程序的登錄跟平時自己這種登錄驗證還不太一樣,多了一個角色,那就是微信服務器。的有效期默認是小時,當用戶一直在使用小程序的話會自動刷新,這個是由微信這邊來維護的。 最近團隊在開發一款小程序,都是新手,一邊看文檔,一邊開發。在開發中會遇到各種問題,今天把小程序登錄這塊的流程整理下,做個記錄。 小程序的登錄跟平時自己APP這種登錄驗證還不太一樣,多了一個角色,那就是微信服務器。 showI...
閱讀 2078·2023-04-25 17:57
閱讀 1284·2021-11-24 09:39
閱讀 2482·2019-08-29 16:39
閱讀 3312·2019-08-29 13:44
閱讀 3117·2019-08-29 13:14
閱讀 2313·2019-08-26 11:36
閱讀 3810·2019-08-26 11:00
閱讀 948·2019-08-26 10:14