)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看这个博客