目录
一、创建字符串
String是用final修饰的,final修饰的不能有子类。
1.1创建字符串的方式
①.直接赋值法:String str="hello word";
字面量:直接写出来的值称为字面量,上面的 "hello word" 就是字符串字面量。
②.通过new来创建字符串对象:String str=new String("hello word");
③.通过char数组来创建字符串:char[] data={'h','e','l','l','o'}; String str=new String(data);
1.2字符串的内存布局
String是一个引用数据类型,引用数据类型默认值为null。
上述代码的内存布局为:
修改str之后,str1不会发生改变:
内存布局为:
二、字符串比较相等
Java中要想比较字符串的内容,必须采用String类提供的equals方法,而String使用 == 比较并不是在比较字符串内容,而是比较两个引用是否是指向同一个对象。
①使用 == 比较:
②使用equals比较:
③equals使用注意事项:
equals有两种使用方式:更推荐使用方式二,因为一旦str为null,方式一的代码就会抛出异常,方式二不会。
三、字符串常量池
JVM会对字符串创建一个字符串的常量池:当使用直接赋值创建字符串时,字面量是第一次出现,JVM就会创建一个String对象并且扔入常量池中,当字面量是第二次或者多次被引用时,并不会创建新的对象,而是复用已有的对象。
a)直接赋值(效率高)
b)采用构造方法
这种做法的缺点:
- 使用String构造方法就会开辟两块堆内存空间,并且其中一块堆内存空间将成为垃圾空间(字符串常量"hello"也是一个匿名对象,用了一次之后就不再使用,就成为垃圾空间,会被JVM自动回收掉)
- 同一个字符串可能会被存储多次,比较浪费空间
为了解决这一问题,我们可以用String的intern方法来手动把String对象加入到字符串常量池中:
四、理解字符串不可变
String类的内部实现是基于char[]来实现的,字符串是一种不可变对象,它的内容不可变。
如上图所示,str的内容没有改变,变的是str的引用。
为何String对象内容不可变?
String对象内容实际上存储在内部value[]数组中,value[]是一个private+final修饰的,private表示value数组出了String类就不可见,无法使用,String类没有提供getter方法,外部无法使用value数组,final表示value指向的地址不可变。
代码示例:
要想修改字符串变量的内容,只能通过反射破坏封装:
由于String的不可变,若需要大量修改字符串内容时,我们使用两个sb类:
StringBuffer:线程安全
StringBuilder:线程不安全
StringBuilder:通过append方法拼接字符串
StringBuilder的其他方法:
①字符串反转
②删除指定范围内的数据
③插入数据
五、字符、字节与字符串
5.1字符和字符串
5.2字节与字符串
六、字符串常规操作
6.1字符串比较
6.2字符串查找
6.3字符串替换
注意:字符串是不可变对象,替换不修改当前字符串,而是产生一个新的字符串。