字符串就是一连串的字符序列,Java提供了String和StringBuffer两个类来封装字符串,并提供了一系列方法来操作字符串对象。
String类是不可变类,即一个String对象被创建后,包含在这个对象汇总的字符序列是不可改变的,直至这个对象被销毁。
StringBuffer对象则代表一个字符序列可变的字符串 。一旦通过StringBuffer生成了最终想要的字符串,就可以调用他的toString()方法将其转换成一个String对象。
JDK1.5版本之后又新增了一个StringBuilder类。与StringBuffer类相似,区别是StringBuilder是非线程安全的,但是性能略高一点。因此通常情况下,如果需要创建一个内容可变的字符串 对象,优先考虑使用StringBuilder类。
String
1.存在哪儿
java.lang包
没有任何继承关系 实现三个接口Serializable, CharSequence, Comparable<String>
2.如何构建对象
String str = "abc"; //直接将字符串常量赋值给str (字符串常量池)
String str = new String();//无参数构造方法创建空的对象
String str = new String("abc");//带string参数的构造方法创建对象
String str = new String(byte[] )//将数组中的每一个元素转化成对应的char 组合成String
String str = new String(char[] )//将数组中的每一个char元素拼接成最终的String
String str =new String(byte[] bytes,Charset charset);//按照指定的字符集将指定byte[]数组解码成一个新的String字符串
String str = new String(StringBuilder builder)/new String(StringBuffer buffer);//通过StringBuilder和StringBuffer对象来创建字符串。
3.String的特性
(1)不可变特性
String类中包含一个private final char[] value;这个char数组就是用来存值的。也就是说String的底层实际上是数组。
体现在两个地方 长度及内容
长度不可变是由于: 数组的长度是固定的,不能改变
内容不可变是由于: 用final修饰数组(引用地址不能改变)
(2)String对象赋值之后就会在常量池中缓存,如果下次创建会判定常量池是否已经有缓存对象,如果有的话直接返回该引用给创建者。
String s1 = "laowang";//内存中会有这个字符串缓存
String s2 =s1;//将s1的引用直接传给s2
String s3 = "laownag";//这里是将s1创建的字符串地址赋给了s3,所以s1和s3指向的是同一个地址
String s4 =new String(s1);
System.out.println(s1==s2);//true
System.out.println(s1==s3);//true
System.out.println(s1==s4);//false
这是因为S3在使用new String()时一定会在堆内存中创建一个内存区,而s2、s3则会直接使用s1的引用。
4.JVM对字符串的优化
根据以前学的知识我们知道,对于String的任何操作其实是创建了一个新对象,然后再把引用地址返回给该对象,但是JVM会对String进行特殊处理,以此来提高程序的运行效率。
例如:
String str = "hi,"+"lao"+"wang";
经过JVM优化后的代码是这样的:
String str = "hi,laowang"
验证代码如下:
5.常用的方法
- boolean = equals(Object obj);
//继承自Object类,在String类中重写了 比较两个字串中的字面值是否相等
- int = hashCode();
//继承自Object ,重写了, 将当前字符串的每一个char元素拆开 乘以31求和
- int = compareTo(String str);