Java String详解
1. 字符串的特点
- String创建
String str1 = new String("hello world");// 构造器创建
String str2 = String.valueOf(123456);// 静态方法创建
String str3="hello world";// 字面量创建
String str4= "hello"+" world";// 拼接创建
String str5 =new Date().toString();// toString方法创建
- String类被finall修饰不可被继承
public final class String{}
- String底层为 finall char[] 数组不可变
private final char value[];
- JVM 为String提供了一个常量池 所有常量池对象都可以共享
String str1="hello world";
String str2="hello world";
System.out.println(str1==str2);// true
- 创建字符串存于常量池的方式
- 字面量创建
- 拼接创建
- 两个指向"…" 的final常量拼接
- 字符串对象.intern()结果放于常量池
String str1="hello world";
String str2="hello"+" world";
System.out.println(str1==str2);// true
final String str3="hello";
final String str4=" world";
System.out.println(str1==str3+str4);//true
String str5 = (str3 + str4).intern();
System.out.println(str1==str5);// true
2. 字符串对象的内存分析
- 例一
String s1="hello";
String s2="hello"
- 例二
String s=new String("hello");
- 例三
String s1="hello";
s1="world";
- 例4(产生三个对象)
String s="hello";
s+="world";
以上忽略哈希值的值问题
String拼接的内存问题:
常量与常量拼接,只会存在于常量池。
只要其中一个为变量,则在堆中。
拼接结果调用intern方法,返回值在常量池中。
-
执行String str4 = new new String(“a”) + new String(“b”) 会创建5个对象;(字符串常量池2个+堆中3个 )
若字符串常量池中已经存在了"a"和"b"则只在堆中创建3个对象。 -
new出来的对象和常量或对象拼接
不会在常量池产生新的字符串
。
String s1="hello ";
String s2="world";
s2=s1+s2;// 对应例4
//通过反射获取value
Class<String> aClass = String.class;
Field value = aClass.getDeclaredField("value");
value.setAccessible(true);
Object o = Object value.get(s2);
String s3="hello world";
String s4="hello"+" world";// 常量和常量---->常量池
Object o1 = value.get(s3);
Object o2 = value.get(s4);
System.out.println(o2==o1);
System.out.println(o==o1);