Java-String字符串的性能优化说明

String对象的实现

在Java8里,String类里面只有两个属性 char[] 数组 hash ,用来存放字符串和hash值,通之前的版本比较,减少了offset 和 count 两个变量,String 对象占用的内存稍微少了些,同时,String.substring 方法也不再共享 char[],从而解决了使用该方法可能导致的内存泄漏问题

String对象的不可变性

不可变性

通过源码可以看出String类使用了 final 关键字进行修饰,表示该类不能被继承重写方法。同时,char[] 数据也被 private 和 final 关键词修饰了,表示这个属性不能被修改。Java 实现的这个特性叫作 String 对象的不可变性,即 String 对象一旦创建成功,就不能再对它进行改变

这样做的好处有哪些呢?

  1. 安全性 确保String对象不会被恶意修改
  2. 唯一性 保证对应的hash值不会频繁变更
  3. 可实现字符串常量池
创建对象的方式

String创建对象的方式有两种:

1.通过字符串常量量的形式创建:String s1 = “abc”

JVM会先检查该对象是否在常量池中存在,如果在,返回该对象的引用,否则在常量池中创建新的字符串。这样做的好处是可以节省内存空间

2.通过new对象生成:String s2 = new String(“abc”)

首先在编译类文件时,"abc"常量字符串将会放入到常量结构中,在类加载时,“abc"将会在常量池中创建;其次,在调用 new 时,JVM 命令将会调用 String 的构造函数,同时引用常量池中的"abc” 字符串,在堆内存中创建一个 String 对象;最后,s2 将引用 String 对象

s2 -> 堆内存中的String对象 -> 常量池"abc"常量字符串

String对象的优化

字符串的 "+"拼接

在日常开发中,经常会使用到字符串拼接,由于String字符串的不可变性,那在拼接过程中是否会产生多个字符串呢?

str= "ab" + "cd" + "ef";

按照拼接逻辑,会产生"ab",“abcd”,"abcdef"三个对象,是非常占用空间和低性能的,针对这个问题JDK给出的优化是在编译过程中将这三个字符串合并成一个,反编译代码如下:

String str= "abcdef";

这样,就只用产生一个"abcdef"字符串了

String.intern是如何节省内存的

intern()是String的一个native方法

public native String intern();

在字符串常量中,默认会将对象放入常量池,在字符串变量中,对象是会创建在堆内存中,同时也会在常量池中创建一个字符串对象,String 对象中的 char 数组将会引用常量池中的 char 数组,并返回堆内存对象引用
当String对象调用intern()时,回去查看字符串常量池中是否有等于该对象的字符串的引用,如果没有,把首次遇到的字符串的引用添加到常量池中;如果有,就返回常量池中的字符串引用,这样相当于一个字符串常量只有一个堆对象引用它,大大地节省了堆内存空间和创建对象的成本

举个例子:

String s1 = new String("abc").intern();
String s2 = new String("abc").intern();
System.out.println(s1 == s2);

输出结果为true,s1和s2的值都是"abc"常量字符串的引用对象,堆内存里值生成了一个对象引用"abc"

但如果s2不执行intern()

String s1 = new String("abc").intern();
String s2 = new String("abc");
System.out.println(s1 == s2);

输出结果为false,这里的s1的值是"abc"常量字符串的引用对象,但是s2的值是堆内存单独生成的一个堆对象,引用了常量池中的"abc"常量字符串

对intern()方法的详细解读和测试请阅读文章:深入解析String#intern

写在最后 欢迎关注微信公众号【小肖爱吃肉】和你一起记录生活的小美好
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值