StringTable

1、String的不可变性

jdk1.8 String类的底层是char型数组实现的
+jdk1.9 String类底层改为byte型数组实现
因为大部分string字符串都是字母,占一个字节,使用char型数组会导致空间浪费。1.9对于中文底层会对byte数组传入编码类型,使其兼容中文

String类是final的,不可以被继承

String的存储是不可变的,无论是拼接字符或替换字符等操作,都是在堆空间的常量池里新开辟空间存放;但常量池不会存储相同内容的字符串
StringTable_第1张图片

class Memory {
    public static void main(String[] args) {//line 1
        int i = 1;//line 2
        Object obj = new Object();//line 3
        Memory mem = new Memory();//line 4
        mem. foo(obj);//line 5
    }//line 9
    private void foo(object param) {//Line 6
        String str = param. toString();//line 7
        System. out. println(str);
    }//line 8
}

StringTable_第2张图片

1.常量与常量的拼接结果在常量池,原理是编译期优化
2.常量池中不会存在相同内容的常量。
3.只要其中有一个是变量,结果就在堆中。变量拼接的原理是StringBuilder
4.如果拼接的结果调用intern()方法,则主动将常量池中还没有的字符串对象放入池中,并返回此对象地址。
StringTable_第3张图片

2、String&StringBuilder

体会执行效率:迪双StringBuilder的append( )的方式添加字符串的效率要远大于使用string的字符串拼接方式
详情:
①stringBuilder的append()的方式: 自始至终中只创建过一个stringBuilder的对象
使用string的字符串拼接方式:创建过多个StringBuilder和String的对象
②使用string的字符串拼接方式: 内存中由于创建了较多的StringBuilder和String的对象,内存占用更大;如果进行GC,需要花费额外的时间。
改进的空间:在实际开发中,如果基本确定要前前后后添加的字符串长度不高于某个限定值highlevel的情况下,建议使用构造器
StringBuilder s = new StringBuilder (highlevel);//new char[highLevel]

3、Intern方法的使用

如果不是用双引号声明的String对象,可以使用string提供的intern方法: intern方法会从字符串常量池中查询当前字符串是否存在,若不存在就会将当前字符串放入常量池中。
●比如: String myInfo = new String(“I love atguigu”).intern() ;
也就是说,如果在任意字符串上调用string.intern方法,那么其返回结果所指向的那个类实例,必须和直接以常量形式出现的字符串实例完全相同。因此,下列表达式的值必定是true:
(“a” + “b” + “c”) .intern() == “abc”
通俗点讲,Interned String就是确保字符串在内存里只有一份拷贝, 这样可以节约内存空间,加快字符串操作任务的执行速度。注意,这个值会被存放在字符串内部池(String Intern Pool) 。
StringTable_第4张图片
StringTable_第5张图片

总结String的intern()的使用:
●jdk1.6中,将这个字符串对象尝试放入串池。
➢如果串池中有,则并不会放入。返回已有的串池中的对象的地址
➢如果没有,会把此对象复制一份,放入串池,并返回串池中的对象地址
●Jdk1.7起,将这个字符串对象尝试放入串池。
➢如果串池中有,则并不会放入。返回已有的串池中的对象的地址
➢如果没有,则会把对象的引用地址复制一份(如果有这个对象的话,没有怎么调用intern,所以是伪命题),放入串池,并返回串池中的引用地址

对于程序中大量存在的字符串,尤其其中存在很多重复字符串时,使用intern() 可以节省内存空间。
因为当调用intern后,所有重复数据会指向堆中字符串常量池(也在堆中,但属于方法区)的已有数据,不会重新再new对象(堆中,不属于方法区),时间效率提升了,而StringTable中的String对象由于后期用不到了,出发gc时会被回收,使得占用内存空间减少

大的网站平台,需要内存中存储大量的字符串。比如社交网站,很多人都存储:北京市、海淀区等信息。这时候如果字符串都调用intern()方法,就会明显降低内存的大小。

你可能感兴趣的:(JVM)