Java String对象

15 4 月, 2021 194点热度 0人点赞 0条评论

为什么String被设计为不可变类

  • 保证String对象的安全性。假设String对象时可变的,那么String对象将可能被恶意修改

  • 保证hash属性值不会频繁变更,确保了唯一性,使得类似HashMap容器才能实现响应的key-value缓存功能

  • 可以实现字符串常量池。在Java中,通常两个创建字符串对象的方式,

    • 通过字符串常量的方式创建String str = "abc"

    • 字符串变量通过new形式的创建String str = new String("abc")

new String("abc")方式创建String对象

通过new String("abc")方式创建String对象时,

  • 在编译类文件时, “abc”常量字符串将会放入到常量结构中

  • 在类加载时, "abc"将会在常量池中创建

  • 在调用new时,JVM命令将会调用String的构造函数,同时引用常量池中的"abc"字符串,在堆内存中创建一个String对象

String.intern方法使用原理

在字符串常量中,默认会将对象放入常量池;

在字符串变量中,对象是会创建在堆内存中,同时也会在常量池中创建一个字符串对象,String对象中的char数据会引用常量池中的char数据, 并返回对内存对象引用

不同版本实现差异

如果调用intern方法,会去查看字符串常量池中是否有等于该对象的字符串的引用,如果没有,在JDK1.6版本中会复制堆中的字符串到常量池中,并返回该字符串引用,堆内存中原有的字符串由于没有引用指向它,将会通过垃圾回收器回收。

JDK1.7版本以后,由于常量池已经合并到堆中,所以不会再复制具体字符串了,只是会把首次遇到的字符串引用添加到常量池中;如果有,就返回常量池中的字符串引用。

使用坑点

使用intern方法需要注意的一点是,一定要结合实际场景,因为常量池的实现是类似于一个HashTable的实现方式,HashTable存储的数据越大,遍历的时间复杂度就会增加。如果数据过大,会增加整个字符串常量吃的负担。

专注着

一个奋斗在编程路上的小伙

文章评论