1、String 类是不可变类,也就是说 String 对象声明后,将不可修改 。
public class StringTest01 {
public static void main(String[] args) {
String s1 = "a";
String s2 = "b";
s1=s1 + s2; //ab
//new String(“a”);
System.out.println(s1);
}
}
String 对象赋值后不能再修改,这就是不可变对象,如果对字符串修改,那么将会创建新的对象。
注意:只要采用双引号赋值字符串,那么在编译期将会放到方法区中的字符串的常量池里,如果是运行时对字符串相加或相减会放到堆中(放之前会先验证方法区中是否含有相同的字符串常量,如果存在,把地址返回,如果不存在,先将字符串常量放到池中,然后再返回该对象的地址)
2、 String s1 = “abc”和 String s2 = new String(“abc”)
public class StringTest02 {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
System.out.println("s1==s2, " + (s1==s2));
System.out.println("s2==s3, " + (s2==s3));
System.out.println("s2 equlas s3," + (s2.equals(s3)));
}
}
➢如果是采用双引号引起来的字符串常量,首先会到常量池中去查找,如果存在就不再分配, 如果不存在就分配,常量池中的数据是在编译期赋值的,也就是生成 class 文件时就把它放到常量池里了,所以 s1 和 s2 都指向常量池中的同一个字符串“abc” ;
➢关于 s3,s3 采用的是 new 的方式,在 new 的时候存在双引号,所以他会到常量区中查找 “abc”,而常量区中存在“abc”,所以常量区中将不再放置字符串,而 new 关键子会在堆中分配内存,所以在堆中会创建一个对象 abc,s3 会指向 abc ;
➢如果比较 s2 和 s3 的值必须采用 equals,String 已经对 eqauls 方法进行了覆盖 。
3、String 面试题分析
String s1 = new String("hello") ;
String s2 = new String("hello") ;
以上代码创建了几个对象?
通过以上分析,创建了 3 个对象,堆区中 2 个,常量池中 1 一个
通过以上分析,使用 String 时,不建议使用 new 关键字,因为使用 new 会创建两个对象
记住:堆区中是运行期分配的,常量池中是编译器分配的。
4、String 常用方法简介
1. endsWith:判断字符串是否以指定的后缀结束
2. startsWith,判断字符串是否以指定的前缀开始
3. equals,字符串相等比较,不忽略大小写
4. equalsIgnoreCase,字符串相等比较,忽略大小写
5. indexOf,取得指定字符在字符串的位置
6. lastIndexOf,返回最后一次字符串出现的位置
7. length,取得字符串的长度
8. replaceAll,替换字符串中指定的内容
9. split,根据指定的表达式拆分字符串
10. substring,截子串
11. trim,去前尾空格
12. valueOf,将其他类型转换成字符串
5、使用 String 时的注意事项
因为 String 是不可变对象,如果多个字符串进行拼接,将会形成多个对象,这样可能会造成内存溢出,会给垃圾回收带来工作量,如下面的应用最好不要用 String。
public class StringTest04 {
public static void main(String[] args) {
String s = "";
for (int i=0; i<100; i++) {
//以下语句会生成大量的对象
//因为 String 是不可变对象
//存在大量的对象相加或相减一般不建议使用 String
//建议使用 StringBuffer 或 StringBuilder
s+=i;// s = s+i;
}
}
}
6、正则表达式初步
正则表达式(独立的学科),主要可以用来做字符串处理,可以描述特定的字符模式,如:”a{2}” 表示由两个字符“a”构成的字符串,等同于普通字符串“aa”,如”\d”代表任意一个数字 0~9, \D 代表所有的非数字,\w 代表所有的英文字母,\W 代表所有的非英文字母。
public boolean matches(String regex),//返回此字符串是否匹配给定的正则表达式。
public String replaceAll(String regex, String replacement) //使用给定的 replacement 字符串替换此 字符串匹配给定的正则表达式的每个子字符串。
public class StringTest05 {
public static void main(String[] args) {
String s1 = "asdd33dfsdaf33ddsd55fdd3dssf4343sdf455ddsdddh565gggh55ddhg";
//将 dd 替换为"中"
System.out.println(s1.replaceAll("dd", "中"));
//将 dd 替换为"中"
System.out.println(s1.replaceAll("d{2}", "中"));
//将数字替换为"中"
System.out.println(s1.replaceAll("\\d", "中"));
//将非数字替换为"中"
System.out.println(s1.replaceAll("\\D", "中"));
}
}