1.String 数据结构演变
java6
String 对象是对 char 数组进行了封装实现的对象,主要有四个成员变量:char 数组、偏移量 offset、字符数量 count、哈希值 hash。String 对象是通过 offset 和 count 两个属性来定位 char[]数组,获取字符串。这么做可以高效、快速地共享数组对象,同时节省内存空间,但这种方式很有可能会导致内存泄漏。
java7/8
java 对 String 类做了一些改变。String 类中不再有 offset 和 count 两个变量了。这样的好处是 String 对象占用的内存稍微少了些,同时,String.substring 方法也不再共享 char[],从而解决了使用该方法可能导致的内存泄漏问题。
String 一直在优化数据结构,减少内存占用。
2.String 对象的不可变性
String 类被 final 关键字修饰了,而且变量 char 数组也被 final 修饰了。所以String 对象一旦创建成功,就不能再对它进行改变。
优势:1.保证 String 对象的安全性。避免 String 对象将可能被恶意修改。
2.保证 hash 属性值不会频繁变更,确保了唯一性
3.可以实现字符串常量池
3.使用 String.intern 节省内存
String a =new String("a").intern();
String b = new String("a").intern();
if(a==b) {
System.out.print("a==b");
}
将对象放入常量池;在字符串变量中,对象是会创建在堆内存中,同时也会在常量池中创建一个字符串对象,String 对象中的 char 数组将会引用常量池中的 char 数组,并返回堆内存对象引用。
调用 intern 方法,会去查看字符串常量池中是否有等于该对象的字符串的引用,如果没有,
在 JDK1.6 版本中会复制堆中的字符串到常量池中,并返回该字符串引用,堆内存中原有的字符串由于没有引用指向它,将会通过垃圾回收器回收。
在 JDK1.7 版本以后,由于常量池已经合并到了堆中,所以不会再复制具体字符串了,只是会把首次遇到的字符串的引用添加到常量池中;如果有,就返回常量池中的字符串引用。
我们在处理大量重复信息的时候,我们可以使用intern 节省内存