Java中String字符串常量池和intern方法源码分析

Java中String字符串常量池和intern方法源码分析

什么是字符串常量池

在Java中,字符串是不可变的,也就是说,对一个字符串的任何操作都将返回一个新的字符串对象,而原来的字符串对象不会被修改。

为了提高String对象的创建和删除效率,Java引入了字符串常量池(String Pool),该池用来缓存字符串对象,可以减少新的String对象的创建数量以及对Java虚拟机内存的占用。

在Java中,运行时常量池是方法区(Method Area)的一部分,在类加载时被初始化,存储编译期生成的各种字面量和符号引用。

String类中intern方法

String类中有一个intern()方法,该方法是一个native方法,用于把String对象添加到字符串常量池中,如果字符串常量池中已经存在了该字符串,则返回常量池中的字符串对象,否则将该对象添加到字符串常量池中,并返回该对象的引用。

例如,假设现有一个字符串池:["abc", "def"],现在需要对字符串"abc"进行intern()操作,操作后返回的引用将是"abc"的地址,同时字符串池中的元素不变,仍然是["abc", "def"]。

intern方法源码分析

Java中String类的intern()方法的源码:

public native String intern();

从源码可以看出,String的intern()方法是一个native方法,也就是说该方法在Java程序之外的C++代码中被实现。在OpenJDK中,这个方法的本地实现大致如下:

static jstring string_pool::intern(Handle string_or_null, TRAPS) {
    if (string_or_null() == NULL) {
        // 如果字符串为null则返回null
        return (jstring)string_or_null();
    }

    // 搜索常量池
    StringTable* const pool = JvmtiExport::string_table();
    Symbol* sym = NULL;
    {
        SharedStrings::LockGuard guard(pool->lock, true);
        sym = pool->lookup_stage2(string_or_null, CHECK_NULL);
    }

    if (sym != NULL) {
        // 字符串在常量池中存在
        return (jstring)sym->ref_str();
    } else {
        // 添加到常量池
        return pool->intern(string_or_null, CHECK_NULL);
    }
}

可以看出,intern()方法的实现比较简单,就是在StringTable中查找该字符串,如果该字符串已经在其中,返回该字符串;否则,将其添加到StringTable并返回该字符串。

示例说明

下面是两个示例,说明了字符串常量池和intern()方法的使用:

示例一:

String str1 = "abc";
String str2 = "abc";
System.out.println(str1 == str2); // true

// 以上代码中,str1和str2都指向字符串池中的"abc",因此相等。

String str3 = new String("abc");
System.out.println(str1 == str3.intern()); // true

// 以上代码中,str3.intern()将"abc"字符串添加到字符串池,并返回池中的字符串引用,
// 因此,str1和str3.intern()都指向字符串池中的"abc",因此相等。

示例二:

String str1 = new String("Hello");
String str2 = "Hello";
System.out.println(str1 == str2); // false

// 以上代码中,str1是用new创建的新的String对象,str2指向字符串池中的"Hello",
// 因此不相等。

String str3 = str1.intern();
String str4 = str2.intern();
System.out.println(str3 == str4); // true

// 以上代码中,str1.intern()将"Hello"添加到字符串池,并返回池中的字符串引用,
// str2.intern()直接返回字符串池中的"Hello",
// 因此str3和str4都指向字符串池中的"Hello",因此相等。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java中String字符串常量池和intern方法源码分析 - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • springboot 如何配置多个jndi数据源

    下面是详细讲解: 配置多个JNDI数据源 在Spring Boot中,可以使用application.properties或application.yml文件配置多个JNDI数据源。下面详细说明如何实现操作。 添加依赖 首先,需要在pom.xml文件中添加JNDI的支持依赖,例如: <dependency> <groupId>org.…

    Java 2023年5月20日
    00
  • Spring Boot整合阿里开源中间件Canal实现数据增量同步

    Spring Boot整合阿里开源中间件Canal实现数据增量同步攻略 简介 Canal是阿里巴巴开源的一款数据库binlog日志解析工具,用于数据增量同步和数据订阅。本文将介绍如何将Canal与Spring Boot整合,实现数据库的增量同步。 环境准备 JDK 8+ Spring Boot Canal 操作步骤 步骤一:引入依赖 在Spring Boot…

    Java 2023年6月2日
    00
  • java实现银行家算法(Swing界面)

    Java实现银行家算法(Swing界面)攻略 银行家算法(Banker’s Algorithm)是一种经典的死锁预防算法,常用于操作系统中。在多进程环境下,进程需要占用资源,但是资源并不足够,如果资源分配策略不合理,则可能会出现死锁的情况。银行家算法通过资源的最大需求量和已分配需求量来判断分配资源是否会导致死锁的发生,从而保障系统运行的安全性。 本文基于Ja…

    Java 2023年5月19日
    00
  • spring boot项目实战之实现与数据库的连接

    Spring Boot项目实战之实现与数据库的连接 概述 Spring Boot是一个快速开发框架,让我们可以专注于业务代码的开发,而不需要关心底层架构的细节。在实际开发中,与数据库的连接是一个非常常见的需求。本文将详细介绍如何在Spring Boot项目中实现与数据库的连接。 步骤 添加Spring Boot依赖 在pom.xml文件中添加如下依赖: &l…

    Java 2023年6月2日
    00
  • MyBatis常见报错问题及解决方案

    MyBatis常见报错问题及解决方案 1. Mapper文件配置错误 MyBatis中最常见的报错就是Mapper文件配置错误,这个错误主要包括以下几种情况: 错误1:XML文件路径配置错误 在mybatis-config.xml配置文件中配置了映射文件地址时,需要注意路径的正确性。如果路径配置错误将会出现找不到对应的XML文件的错误。可以采用以下配置方式解…

    Java 2023年5月20日
    00
  • 深入了解Springboot核心知识点之数据访问配置

    深入了解Spring Boot核心知识点之数据访问配置 Spring Boot是一个非常流行的Java框架,它提供了许多便利的功能,其中包括数据访问。在本文中,我们将深入了解Spring Boot的数据访问配置,包括如何配置数据源、如何使用JdbcTemplate和如何使用Spring Data JPA。 配置数据源 在Spring Boot中,我们可以使用…

    Java 2023年5月15日
    00
  • JVM面试和学习中需要注意的部分

    在学习jvm的时候许多人处于迷茫的状态,对一些基础的知识反而听过就忘了,这篇笔记是我在学习jvm的时候随手记的一些,适合已经学过或者了解过的小伙伴复习回顾一下,当然知识的覆盖是没有的,主要记录了我觉得容易忘记或者记错的知识点,这些有很多是基石知识,希望大家不要忘记,大家看到就当正好复习一下,对大家的面试可能会有一点小小的帮助 内存结构 1.方法区用来存储类加…

    Java 2023年5月8日
    00
  • 详解Java程序读取properties配置文件的方法

    当我们需要在Java程序中读取一些配置信息时,通常可以使用Properties文件作为配置文件,这种方式比硬编码更加灵活、易于维护。 以下是读取Properties配置文件的方法: 准备Properties文件 首先需要准备一个Properties文件。文件扩展名通常为.properties,它是一个文本文件,可以使用任何文本编辑器来编辑。属性文件由键值对组…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部