概述
创建字符串对象,和其他普通对象一样,会占用计算机的资源(时间和空间),作为最常用的数据类
型,大量频繁的创建字符串对象,会极大程度地影响程序的性能。
JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化
- 为字符串开辟一个字符串常量池,类似于缓存区
- 创建字符串常量时,首先会检查字符串常量池中是否存在该字符串,如果存在该字符串,则返回该实例的引用,如果不存在,则实例化创建该字符串,并放入池中
案例
public static void main(String[] args) {
//new String() 创建了2个对象 堆中一个字符串常量池一个
// a地址仍指向堆
String a = new String("a");
String b = new String("a");
System.out.println(a==b);//false
System.out.println(a);
System.out.println("----------------------------");
String e = "a"+"b";
String f = "ab";
String g = a+b;//堆中地址
System.out.println(g==f);//false
//拼接的本质
//new StringBuilder.append(a).append(b).toString()
System.out.println(e==f);//true
System.out.println(a.equals(b));//true只比较字符串
String c = "a";
String d = "a";
System.out.println(c==d);//true,c和d是存在字符串常量池中(JDK8后)
final String h= "a";
final String i= "b";//常量//宏变量
String j = h+i;
System.out.println(j==f);//true
System.out.println("-----------");
String k = new String("a");//手动new
String knew = k.intern();//将字符串对象指向字符串常量池 并返回地址
String l = "a";
System.out.println(k==l);//false
System.out.println(knew==l);//true
System.out.println("-----------------");
String m ="J";
String n ="Q";
String o =m+n;
o.intern();//返回常量值的引用
String p ="JQ";
System.out.println(o==p);//true
//intern
//如果常量池已经存在 不会放入常量池中 但会返回常量地址
//如果不存在 放入常量池 重新指向常量池地址 也会返回常量池中地址
}
字符串不可变
- 自身没有提供操作value[]数组的公有方法
- 此类由final修饰 没有子类继承 也无法通过子类去操作次value[]数组