一文带你深入了解Java String的不可变性

 更新时间:2023年06月26日 10:12:45   作者:东方甲乙木土  
这篇文章主要来和大家一起深入探讨一下Java String中的不可变性,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下

String 类

String 类结构

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
        // ...
    }

Java String 类是 java.lang 包中的类,其实现了 java.io.Serializable, Comparable, CharSequence 等接口。

String 类对象中存储的字符串,最终都是以字符形式存储在其 char[] 数组中,获取时从数组中读取字符列表,且 String 中该属性使用了 final 关键字定义。

private final char value[];

除此之外,String 类在 Object 的基础上重写了 equals() 和 hashCode() 方法,

  • equals() 除了使用 == 判断相等外,还会遍历循环比较两个字符串对应字符串数组中的每个字符,如果完全相同也会认为字符串相等。
  • toString() 方法直接返回字符串本身,因为其就是字符串,无需 toString 转换
public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

String 的不可变性怎么理解

Java 中 String 类是不可变的,这意味着一旦创建了一个 String 对象,就不能再修改它的值。

String str = "abc";
str = "123";
System.out.println(str); // 输出 123
  • 上述代码看似是改变了字符串内容,但是实际上只是将变量 str 指向的地址由 "abc" 改成了 "123",在字符串常量池中 "abc" 仍然存在,不被改变。
  • 对于 String 提供的 trim()、replace() 等修改字符串字面值的方法也是同理,都是重新创建一个字符串返回,并没有修改原始字符串。

String 类的不可变性体现在如下方面:

1.String 类使用 final 修饰,保证该类不会被继承进行修改

2.String 类中存储内容的 char [] 使用 final 修饰,保证字符数组引用不会被修改

3.尽管 String 类的 char[] 中的元素仍可以修改,但是又通过如下两种方式控制不被修改

  • char[] 定义为 private ,即不可以从外部进行操作
  • String 类中所有内部方法都避免操作 char[] 内容

基于上述内容,保证了 String 的 char[] 内容是不可变的,即 String 的不可变性。

由于 String 类是不可变的,所以它的性能比较高,且是线程安全的,即多个线程可以同时访问同一个 String 对象,而不会出现线程问题。

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
    //...
}

String 类的常用方法都有那些

  • length():返回字符串长度
  • trim():去除字符串两端空白。
  • toLowerCase():将字符串转成小写字母。
  • toUpperCase():将字符串转成大写字符。
  • charAt(int index):返回指定索引处的字符。
  • inexOf(char c):返回指定字符的索引。
  • replace():字符串替换。
  • split():分割字符串,返回一个分割后的字符串数组。
  • substring (int beginIndex, int endIndex):返回从 beginIndex 到 endIndex-1 的子字符串。
  • equals(Object obj):字符串比较是否相等。
  • getBytes():返回字符串的 byte 类型数组。

String 常用工具类

StringUtils 是处理字符串的工具类,String 类实现 CharSequence 接口,为实现不同的 String 操作,各大厂商封装了相应的 StringUtils 工具类。

org.springframework.util.StringUtils,spring 自带 String 工具类,可以满足基本的使用。

Java Web 中不需要导包,在 spring-core 包中存在,可以直接使用

org.apache.commons.lang.StringUtils, apache 提供的 String 工具类,对 java.lang 的扩展。

lang 最新版本是 2.6,最低要求 Java1.2 以上,目前官方已不再维护。

apache-commons-lang3.StringUtils,lang 的升级包,将参数换成 CharSequence 数组,贴合 String 类型的内部结构,最常用工具类包。

lang3 目前最新版本是 3.12.0,最低要求 Java8 以上。相对于 lang 来说完全支持 Java8 的特性,废除了一些旧的 API。该版本无法兼容旧有版本,于是为了避免冲突改名为 lang3。

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.6</version>
</dependency>

到此这篇关于一文带你深入了解Java String的不可变性的文章就介绍到这了,更多相关String不可变性内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring Boot Swagger3常用注解详解与实战指南

    Spring Boot Swagger3常用注解详解与实战指南

    Swagger是一个用于设计、构建、文档化和使用RESTful Web服务的开源工具,Swagger3是Swagger的最新版本,它提供了许多新功能和改进,这篇文章主要介绍了Spring Boot Swagger3常用注解详解与实战指南的相关资料,需要的朋友可以参考下
    2025-10-10
  • spring mybatis环境常量与枚举转换示例详解

    spring mybatis环境常量与枚举转换示例详解

    这篇文章主要为大家介绍了spring mybatis环境常量与枚举转换示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • 超详细讲解SpringCloud Commons公共抽象的用法

    超详细讲解SpringCloud Commons公共抽象的用法

    这篇文章主要介绍了超详细讲解SpringCloud Commons公共抽象的用法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • Spring中RedisTemplate使用方法详解

    Spring中RedisTemplate使用方法详解

    Spring封装了一个比较强大的模板,也就是redisTemplate,方便在开发的时候操作Redis缓存,这篇文章主要给大家介绍了关于Java中RedisTemplate使用方法的相关资料,需要的朋友可以参考下
    2023-12-12
  • 剑指Offer之Java算法习题精讲链表与字符串及数组

    剑指Offer之Java算法习题精讲链表与字符串及数组

    跟着思路走,之后从简单题入手,反复去看,做过之后可能会忘记,之后再做一次,记不住就反复做,反复寻求思路和规律,慢慢积累就会发现质的变化
    2022-03-03
  • Guava范围类Range方法实例深入解析

    Guava范围类Range方法实例深入解析

    这篇文章主要为大家介绍了Guava范围类Range方法实例深入解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • 深入浅出讲解Java中的枚举类

    深入浅出讲解Java中的枚举类

    这篇文章主要介绍了深入浅出讲解Java中的枚举类,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • Springboot常用方法参数注解示例详解

    Springboot常用方法参数注解示例详解

    这篇文章主要介绍了Springboot常用方法参数注解及示例,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-08-08
  • Spring3整合MyBatis实现分页查询和搜索功能

    Spring3整合MyBatis实现分页查询和搜索功能

    本文详细介绍了如何在SpringBoot和MyBatis框架下实现分页查询和搜索功能,结合Vue和ElementUI构建前端界面,通过配置PageHelper插件,编写动态SQL,封装统一的请求工具,本文结合示例代码讲解的非常详细,感兴趣的朋友一起看看吧
    2026-01-01
  • java.sql.Date和java.util.Date的区别详解

    java.sql.Date和java.util.Date的区别详解

    Java中有两个Date类,一个是java.util.Date通常情况下用它获取当前时间或构造时间,另一个是java.sql.Date是针对SQL语句使用的,它只包含日期而没有时间部分,这篇文章主要给大家介绍了关于java.sql.Date和java.util.Date区别的相关资料,需要的朋友可以参考下
    2023-03-03

最新评论