)1.string是不可變對象。
由於字符串對象在常見開發時廣泛使用,那么在頻繁使用同一個字符串的時候,會出現頻繁創建該字符串的情況。java為此做了一個優化措施。使得string對象為不可變對象。也就是說,string對象一旦創建出來,他的數據值是不會再變化的。變化的僅僅是引用的地址罷了。string不可變的好處在於我們在編程的時候可以重用string對象,而不是反復的創建,徒耗內存。
例如 string a = “123”;
string b = a;
a = “456”;
system。out。println(a == b); // false 也就是說,我們常見的字符串中的改變,實質是新建了一個新的字符串對象,並把引用返回罷了。源字符串對象的數據值一旦創建,就不能改變了。
)2.string常量池
當我們通過字面量,常量來初始化一個字符串時,JVM首先會從字符串的常量池(一個JVM內部維護的內存區域,用來保存已經創建過的字符串對象)中查詢用來保存該字符串的對象是否存在,若存在則直接引用,若不存在則創建該字符串對象並存入常量池,然后引用它。因為字符串內容不能改變,所以我們可以放心的重用他們。如果我們用的是new來創建字符的話,那么也會創建出堆中的字符串對象。
)2.1常量池的變遷:
jdk1.6以及之前:常量池存在於方法區中。jdk1.7,常量池放到了堆中。jdk1.8之后,常量池放到了元空間中。
)3.內存編碼以及長度 : length() 方法
java存儲每一個字符都是兩個字節,采用Unicode編碼,並且任何字符(無論是中文還是英文還是空格),每個字符長度都是1。所以字符串的長度就是該字符串中字符的個數。 int length();方法返回字符串的長度
例如:String str = “123abc”;
int res = str.length();
)4.indexOf /lastIndexOf實現檢索
int indexOf(string ch):用來檢查給定的一個字符在當前字符串中第一次出現的下標位置。這里的下標和數組的下標意思相近,0表示該字符串的第1個字符,以此類推。當該字符串中並不包含給定的字符時,那么該方法返回-1。lastIndexOf用來檢查給定的字符在當前字符串中最后一次出現的索引值。
例如:
- String str = "HelloWorld";
- System.out.println(str.indexOf('W'));//5
- System.out.println(str.indexOf('h'))//-1
)5.使用subString來獲取子串
String subString(int begin, int end):用來截取當前字符串的部分內容來獲取這個子串。begin代表從哪里開始,end表示到哪里結束。且這個截取,含頭不含尾。換句話說就是包括開始的下標,但是不包括結束的下標。
String subString(int begin) :begin表示截取的開始,然后從該點開始到該字符串結束。
例如
String str = “HelloWorld”;
String subStr = str。subString(0,5);
System.out.println(”subStr“);//Hello
)5.1詳細刨析subString方法中返回的String對象的歸屬問題。
例子5.11
String a = new String(”HelloWorld");
String b = a.subString(0);
String c = "HelloWorld";
System.out.println(a == b); // true
System.out.println(b == c); // false
首先,a指向的是存儲在堆空間的string對象。當substring沒有做任何改動的時候,實際是把a的引用地址返回給b。這時候,b也指向了堆中的HelloWorld對象。而c指向的是存儲在常量池中的對象。那么,a和b自然相等,而b和c不相等。如果我們把第一句改一下,變成String a = “HelloWorld”;那么這時候,a和b相等,b和c也相等。也就是說,subString在不做任何更改的時候,就是把原字符串對象的引用返回。無論原字符串是在常量池中還是在堆中。
例子5.12
String a = “HelloWorld”;
String b = a.subString(0,5);
String c = "Hello";
String d = new String("Hello");
System.out.println(b == c); //false
System.out.println("b == d");// false
首先,a指向的是常量池中的HelloWorld對象,b截取a,發生變化之后,b指向的是堆中新建(new)出來的Hello對象,此時c是指向常量池中的對象,d是指向堆中一個新的Hello對象,因此b不等於c,b也不等於d;將第一句改成 String a = new String(“HelloWorld”);后,結果還是一樣。也就是說,當subString改變了一個字符串的時候,會在堆中新建一個對象(通過new的方式),並將地址返回給引用。無論源字符串是來源於常量池中還是堆中。
)6 用trim來去除空白字符串首尾兩端的空白字符,例如空格,縮進。
例子: String a = “ abc code ”//前面有兩個空格,中間有兩個空格,后面有四個
String res = a.trim();
Systen.out.println(a.length()); // 15
System.out.println(res.length());//9
System.out.println(res); // abc code 中間的兩個空格保留,前后兩端的去除
)6.1 trim()方法返回的對象的歸屬問題,以及內部具體運行問題
)6.1.1例子
String a = "HelloWorld";
String b = a.trim();
String c = "HelloWorld";
String d = new String("HelloWorld");
System.out.println(a == b); // true
System.out.println(b == c); // true
System.out.println(b == d);// false
首先,a是指向常量池中的HelloWorld,由於a首尾兩端沒有空格,因此,trim方法直接返回a的地址給b。這時,b也是指向常量池中的HelloWorld。c是指向常量池中的HelloWorld,d是堆中新建的HelloWorld。因此,a和b相等,b和c相等,b和d不等。如果我們把第一句代碼改成 new的類型,此時a指向的是堆中創建的HelloWorld,b也是指向該對象,此時,a和b還是相等,但是b和c、d之間都不相等了。也就是說,當trim方法沒有改變源字符串的數據時,本質是返回源字符串的地址,無論源字符串位於常量池中還是堆內存中。
)6.1.2例子
String a = " HelloWorld ";
String b = a.trim();
String c = "HelloWorld";
String d = new String("HelloWorld");
結果為 :a == b//false b == c//false b == d//false. 將第一句中的a改為new出來,結果也一樣
也就是說,當trim改變了源字符串中的數據時,不管源字符串的位置(常量池還是堆中),都會在堆中新建一個字符串對象,並返回引用。
)7.char charAt(int index):給定一個下標位置,返回具體字符
)8. boolean startsWith(String inp) boolean endsWith(String inp) :判斷源字符串是否以給定的字符串開始或者結束,注意大小寫敏感
)9.大小寫變化
)String toUpperCase() :用來將源字符串中的英文部分的字符全部轉化為大寫再將新的字符串返回。
)String toLowerCase() :用來將源字符串中的英文部分的字符全部轉化為小寫字母再將新的字符串返回。
返回的對象的歸屬和trim,subString一樣。如果方法沒有改變源字符串,那么就會返回源字符串的內存地址,無論源字符串在池中還是堆中。如果方法改變了源字符串的數據,那么就會在堆中新建一個新的字符串,並將地址返回。無論源字符串在池中還是堆中。
)10.其他的類型向string類型轉化
)11.String intern()
http://www.cnblogs.com/xuyunqi/p/7928435.htmlkanka看這個博客