三大核心特性
① 不变性:是一个immutable模式的对象,不变模式的主要作用是当一个对象被多线程共享并频繁访问时,保证数据的一致性。
immutable模式:是一种持久化数据,一旦创建就不会被修改,修改也直接返回新的immutable,原数据不会发生变化。
原理:因为深拷贝对性能的消耗太大了(用到了递归,逐层拷贝每个节点),但当你使用immutable数据的时候只会拷贝你改变的节点,从而达到了节省性能。
② 常量池优化:String对象创建之后,会在字符串常量池中进行缓存,下次创建同样的对象时,会直接返回缓存的引用。
字符串常量池:在堆内存中
③ final:String类不可被继承,提高了系统的安全性。
两种实例化
① 直接赋值
String str = "hello"; //值存放在字符串常量池中
② 使用构造函数
String str1 = new String("hello"); //值存放在堆内存中 char[] chars = {'h','e','l','l','o'}; String str2 = new String(chars);
equals 方法重写
重写了Object的equals方法(默认是 ==,比较的是栈中的信息,基本数据类型是值,引用数据类型是地址信息),将字符串转换为byte[],遍历比较每个数组中的字符值,即比较的是字符串的值。
intern 方法
当调用某个字符串对象的intern()方法时,会去字符串常量池中寻找,如果已经存在一个值相等的字符串,则直接返回该对象的引用。如果不存在,则在字符串常量池中创建该对象并返回。
String str1 = "hello"; //值存放在常量池中 String str2 = new String("hello"); //值存放在堆内存中 System.out.printf(str1 == str2); //false System.out.printf(str1 == str2.intern()); //true
常用的方法
① 字符串截取
public String subString(int beginIndex); //从beginIndex开始到结尾 public String subString(int beginIndex, int endIndex); //从beginIndex开始到endIndex,不包含endIndex
② 字符串分割
public String[] split(String regx); //按一个分隔符对字符串进行分割,返回字符串数组,支持正则表达式 String str = "Hello,World;Java-String"; String[] arr = str.split("[,|;|-]"); // [Hello,World,Java,String]
String 是线程安全的吗
是线程安全的,因为String是不可变的。
String、StringBuilder、StringBuffer的区别
① String 是不可变的,另外两个是可变的
② StringBuffer是线程安全的(字符串的操作方法使用了synchronized修饰),StringBuilder不安全