Java中String类详解

String:字符串类,不可继承(扩展)该类,一切基于字符串类之上的扩展皆是新字符串对象实例的创建,故代码运行速度最慢。

StringBuffer:字符串缓冲类,可扩展,线程安全(使不同的线程同时操作该类的对象实例时,保证操作的原子性),类中维护了一个不写入字节码文件的字符数组类型,便于转换成字符串类型,调用了Arrays.copyOfRange方法(本地方法包装的一个方法)。

StringBuilder:字符串构造者类,线程不安全,提供单线程的字符串修改功能,能够快速地构造及修改字符串,故运行速度最快。

 

在jvm中与字符串息息相关的Java内存区域是运行时常量池、java堆及java堆中的字符串常量池。

运行时常量池:

.java文件编译时会生成各种字面量和符号引用,在.class文件加载到虚拟机后,用class对象实例来存数据,会存放到方法区(永久代)中的运行时常量池。(JDK7及JDK7以后方法区被替换成元数据区,运行时常量池中的字符串常量池被调入到堆中),

字面量:

由字母和数字构成的字符串或者数值。

扫描二维码关注公众号,回复: 5851867 查看本文章

符号引用:

以一组符号来描述所引用的目标(编译时产生),由于jdk中的编译器在编译文件时并不知道所引用的类的实际地址,因此只能使用符号引用来代替。在类加载的解析步骤,符号引用会被解析成直接引用。

 

字符串常量池:类似一个Set数据结构一样,里面存的数据是字符串实例的引用,满足不重复、无排序的规则。

字符串常量池所附带的思想:共享带来的高效率远远胜于提取、拼接字符串所带来的效率。

 

下面是两种字符串创建方法简介:

1、String  str1  =  “hello1”;

查看字符串常量池是否存在””中的字面值

     不存在则在堆中创建该字符串的实例,返回该常量的地址并存入池中

     存在则返回该实例的地址

返回后再赋值给String对象的引用

 

2、String str2 = new String(“hello2”);

遇到new 指令会到运行时常量池检查是否能定位到相同类的符号引用

     如果能则检查该类是否被加载、解析和初始化过

          如果没有,必须先执行相应的类的加载过程

          如果有,则分配空间,进行初始化和赋初始值

     如果不能则创建新的符号引用,并进行类的加载,再执行另外的步骤

“hello”所做的工作同1是一样的,最后返回的引用值给str对象中的字符串数组的引用类型(字面量的底层实现)

故而new一个字符串对象返回的地址值是不同于创建一个字符串常量返回的地址值

本人并未看过JVM源码,故以上是综书和博客,表己见,大佬请多指教。

猜你喜欢

转载自blog.csdn.net/qq_40254236/article/details/86562736