专注Java教育14年 全国咨询/投诉热线:400-8080-105
动力节点LOGO图
始于2009,口口相传的Java黄埔军校
首页 学习攻略 Java学习 Java字符串常量池的用法分析

Java字符串常量池的用法分析

更新时间:2022-11-24 10:42:34 来源:动力节点 浏览900次

当您在 Java 中声明一个新字符串时,幕后会发生一些有趣的事情。这是一个基本的字符串声明。我们创建一个名为employee的新字符串变量并为其赋值,如您在代码中所见:

String employee = "Edgar Allen Poe" ; 

Java 不仅会创建变量employee,还会在内存中为文字值“Edgar Allen Poe”分配空间。内存中的这个区域称为字符串常量池。它就像一个可供程序其他部分使用的字符串值池。

现在,如果您创建了另一个变量,比如employee2,并且还给它赋值“Edgar Allen Poe”,Java 将简单地重新使用池中已有的值。

您会注意到字符串常量池位于一段称为堆的内存中。这是内存的一部分,用于运行时操作,处理类和对象。把一堆想象成一块花园土壤,当你种植花园时,你可以很容易地从中取出泥土和植物。Java 将这些新对象放在那里。如果你再创建一百个对象,Java 将在堆顶上再创建一百个文字。

用法解析

1. 直接使用双引号声明出来的String对象

String employee3 = new String ( "Edgar Allen Poe" );  

创建过程:JVM会使用常量池来管理字符串直接量。在执行这句话时,JVM会先检查常量池中是否已经存有"abc",若没有则将"abc"存入常量池,否则就复用常量池中已有的"abc",将其引用赋值给变量a。

2. 使用new方法创建出来的String对象

可以使用String提供的intern方法。

String s2 = new String("abc");

在执行这句话时,JVM会先使用常量池来管理字符串直接量,String 先使用 intern 方法会从字符串常量池中查询当前字符串是否存在,若不存在就会将当前字符串放入常量池中,即将"abc"存入常量池。然后再创建一个新

的String对象,这个对象会被保存在堆内存中。并且,堆中对象的数据会指向常量池中的直接量。

例如下面代码进行对abc常量进行检测是否存在的测试:

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

测试案例

运行如下代码:

public class Test{
    public class void main(String[] args){
		String s1 = "abc";
        String s2 = "abc";
        System.out.println("s1="+s1);//abc
        System.out.println(s1 == s2);//true
        System.out.println("=================");
        char[] charArray = {'a','b','c'};
        String s3 = new String(charArray);
        System.out.println("s3="+s3);//abc
        System.out.println(s1 == s3);//false
        System.out.println("=================");
        String s4 = new String("abc");
        System.out.println("s4="+s4);//abc
        System.out.println(s1==s4);
        System.out.println("=================");
​    }
}

运行结果如下:

虽然两个输出两个字符串的结果相同,都为abc,但比较两者时则不同,这是因为比较的规则为:

引用类型比较时,比较的是其地址值;

基本数据类型比较的是其数据值。

采用直接创建String类型对象的方法创建对象时,JVM首先会去字符串常量池中查找是否存在"abc" 这个对象,如果不存在,则在字符串常量池中创建”abc“这个对象,然后将池中”abc“对象的引用地址返回给对象s1,这样s1的地址就在常量池中;

如果存在,则不创建任何对象,直接将存在的“abc”的地址返回给对象s2。这就是为什么s1等于s2的原因。

而通过new方法创建的String对象,其创建的字符串是放在堆当中的,将堆当中的字符串地址返回赋值给s3,s1和s3的存放地址不相同,一个在字符串常量池中,一个在堆当中,字符串常量池外,因此返回的值是false。s4同样如此。

提交申请后,顾问老师会电话与您沟通安排学习

免费课程推荐 >>
技术文档推荐 >>