编程语言
首页 > 编程语言> > Java常用类--String类(String的不可变性 & 字符串常量池 & 享元模式)

Java常用类--String类(String的不可变性 & 字符串常量池 & 享元模式)

作者:互联网

1.String的不可变性

当我们去阅读源代码的时候,会发现有这样的一句话:
在这里插入图片描述我想大家应该就知道为什么String不可变了,String类被final修饰,官方注释说明创建后不能被改变,但是为什么String要使用final修饰呢?
在这里插入图片描述

了解一个经典的面试题

    public static void main(String[] args) {
        //        创建字符串对象
        String a = "abc";
        String b = "abc";
        String c = new String("abc");
        System.out.println(a == b); //true
        System.out.println(a.equals(b)); //true
        System.out.println(a == c); //false
        System.out.println(a.equals(c)); //true
    }

内存图分析:

在这里插入图片描述

分析:

因为String太过常用,JAVA类库的设计者在实现时做了个小小的变化,即采用了享元模
式,每当生成一个新内容的字符串时,他们都被添加到一个共享池中,当第二次再次生成
同样内容的字符串实例时,就共享此对象,而不是创建一个新对象,但是这样的做法仅
仅适合于通过=符号进行的初始化。

String不可变的好处:


2. 字符串常量池

常量池表(Constant_Pool table)

运行时常量池(Runtime Constant Pool)

字符串常量池(String Pool)

亨元模式

详细分析

        int x = 10;
        String y = "hello";
  1. 首先, 10 和 “hello” 会在经过javac(或者其他编译器)编译过后变为Class文件中constant_pool table(常量池表) 的内容。
  2. 当我们的程序运行时,也就是说JVM运行时,每个Class constant_pool table 中的内容会被加载到JVM内存中的方法区中各自Class的 Runtime Constant Pool。
  3. 一个没有被String Pool包含的Runtime Constant Pool中的字符串(这里是"hello")会被加入到String Pool中(HosSpot使用hashtable引用方式),步骤如下:
    1. 在Java Heap(堆)中根据"hello"字面量create一个字符串对象
    2. 将字面量"hello"与字符串对象的引用在hashtable中关联起来键 - 值(形式是:“hello” = 对象的引用地址。)

另外来说,当一个新的字符串出现在Runtime Constant Pool中时怎么判断需不需要在Java Heap中创建新对象呢?

举例:

在这里插入图片描述



标签:享元,String,JVM,字符串,可变性,Class,Pool,常量
来源: https://blog.csdn.net/I_r_o_n_M_a_n/article/details/118904539