String类分析(JDK1.8)

本文详细分析了Java 1.8中String类的内部实现,包括其不可变性的原因,以及由此带来的安全性与效率提升。字符串常量池的概念也被提及,解释了如何通过不同方式创建String对象以及内存分配的过程。此外,还讨论了String对象的拼接效率问题以及intern()方法的作用,该方法用于在常量池中查找或创建具有相同值的字符串。
摘要由CSDN通过智能技术生成

String类分析(JDK1.8)

 

1、源码

String 对象是对 char 数组进行了封装实现的对象, 主要有 2 个成员变量: char 数组, hash

 

2、String对象的不可变性

String类被final关键字修饰了,变量char 数组也是final修饰了。不可继承修改。

 

3、优点

  1. 保证 String 对象的安全性。假设 String 对象是可变的,那么 String 对象将可能被恶意修改。
    b、保证 hash 属性值不会频繁变更,确保了唯一性, 使得类似 HashMap 容器才能实现相应的 key-value 缓存功能。
    c、可以实现字符串常量池。在Java 中通常有两种创建字符串对象的方式一种是通过字符串常量的方式创建String str=abc”; 另一种是字符串变量通过 new 形式的创建String str = new String(abc) 

 

4、String 的创建方式及内存分配的方式

a、String str=“abc”

当代码中使用这种方式创建字符串对象时, JVM 首先会检查该对象是否在字符串常量池中, 如果在, 就返回该对象引用,否则新的字符串将在常量池中被创建。 这种方式可以减少同一个值的字符串对象的重复创建,节约内存。(str 只是一个引用)。

 

b、String str = new String(“abc”)

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

  1. 使用 new, 对象会创建在堆中, 同时赋值的话, 会在常量池中创建一个字符串对象, 复制到堆中。具体的复制过程是先将常量池中的字符串压入栈中, 在使用 String 的构造方法是, 会拿到栈中的字符串作为构方法的参数。这个构造函数是一个 char 数组的赋值过程, 而不是 new 出来的, 所以是引用了常量池中的字符串对象。 存在引用关系。

 

编程过程中, 字符串的拼接很常见。 前面我讲过 String 对象是不可变的, 如果我们使用 String 对象相加, 拼接我们想要的字符串, 是不是就会产生多个
对象呢? 例如以下代码:
分析代码可知: 首先会生成 ab 对象, 再生成 abcd 对象, 最后生成 abcdef 对象, 从理论上来说, 这段代码是低效的。
编译器自动优化了这行代码, 编译后的代码, 你会发现编译器自动优化了这行代码, 如下
String str= "abcdef"; 

 

5、Intern()


String 的 intern 方法, 如果常量池中有相同值, 就会重复使用该对象, 返回对象引用

String提供的intern方法,String.intern()是一个Native方法,它的作用是:如果运行时常量池中已经包含一个等于此String对象内容的字符串,则返回常量池中该字符串的引用,如果没有,则在常量池中创建与String内容相同的字符串,并返回常量池中创建的字符串的引用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值