Java String 为什么不可变? 真的吗?

简介: Java String 为什么不可变? 真的吗?

众所周知:



Stirng是个不可变的类,因为使用了final来修饰(真的只是这个一个final的功劳吗? ),如:


image.png


又有一个众所周知:



就是 String的本质是一个char[] 数组


所以为了确保String真的不可变,那么本质肯定不能变,于是乎这个char[]数组,如:


image.png


而且这个成员变量是没有提供set和get方法。


看到这里,其实可以知道的就是,如果这个value数组的元素被改变了,那么String就是被改变了。


所以在String的源码里,诸多方法里面都没有涉及到直接去修改value[]的元素。

 

再度聚焦:image.png


这个构造函数,一眼能看明白意思,就是通过传递一个char 数组,进行构造出一个新的String。


但是又细眼一看?


 image.png


这里使用到了Arrays的copyOf方法去实现深拷贝:


image.png


这样做的原因大家都知道,就是重新开辟一波新的空间,这样防止 在后续修改传入的char value[] 里的元素,导致String也跟着被修改(如果写成 this.value=value)


霸王硬上弓:



那么咱们就是要修改String,怎么办?


那肯定就是修改它的本质 char[] value的元素了。


咱们通过反射去修改String的成员变量,也就是这个本质 char数组,一起来看看:


    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        String testStr = "JCccc";
        System.out.println("一开始的testStr值为 : " +testStr);
        System.out.println(testStr.hashCode());
        //反射机制,获取获取String里面的的value字段
        Field valueFieldOfString = String.class.getDeclaredField("value");
        //设置value属性的访问权限为true
        valueFieldOfString.setAccessible(true);
        //获取s对象上的value属性的值
        char[] value = (char[]) valueFieldOfString.get(testStr);
        //改变value数组中的元素
        value[1] = 'A';
        value[2] = 'a';
        System.out.println("被操作之后的testStr为 : " +testStr);
        System.out.println(testStr.hashCode());
    }


看一下效果:


image.png


好了,该篇就到此。

相关文章
|
4月前
|
Java 索引
java基础(13)String类
本文介绍了Java中String类的多种操作方法,包括字符串拼接、获取长度、去除空格、替换、截取、分割、比较和查找字符等。
50 0
java基础(13)String类
|
30天前
|
存储 JavaScript Java
Java 中的 String Pool 简介
本文介绍了 Java 中 String 对象及其存储机制 String Pool 的基本概念,包括字符串引用、构造方法中的内存分配、字符串文字与对象的区别、手工引用、垃圾清理、性能优化,以及 Java 9 中的压缩字符串特性。文章详细解析了 String 对象的初始化、内存使用及优化方法,帮助开发者更好地理解和使用 Java 中的字符串。
Java 中的 String Pool 简介
|
1月前
|
缓存 安全 Java
java 为什么 String 在 java 中是不可变的?
本文探讨了Java中String为何设计为不可变类型,从字符串池的高效利用、哈希码缓存、支持其他对象的安全使用、增强安全性以及线程安全等方面阐述了不可变性的优势。文中还通过具体代码示例解释了这些优点的实际应用。
java 为什么 String 在 java 中是不可变的?
|
3月前
|
Java 测试技术 开发者
Java零基础-indexOf(String str)详解!
【10月更文挑战第14天】Java零基础教学篇,手把手实践教学!
132 65
|
2月前
|
JSON Java 关系型数据库
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
在Java中,使用mybatis-plus更新实体类对象到mysql,其中一个字段对应数据库中json数据类型,更新时报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
156 4
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
|
5月前
|
Kubernetes jenkins 持续交付
从代码到k8s部署应有尽有系列-java源码之String详解
本文详细介绍了一个基于 `gitlab + jenkins + harbor + k8s` 的自动化部署环境搭建流程。其中,`gitlab` 用于代码托管和 CI,`jenkins` 负责 CD 发布,`harbor` 作为镜像仓库,而 `k8s` 则用于运行服务。文章具体介绍了每项工具的部署步骤,并提供了详细的配置信息和示例代码。此外,还特别指出中间件(如 MySQL、Redis 等)应部署在 K8s 之外,以确保服务稳定性和独立性。通过本文,读者可以学习如何在本地环境中搭建一套完整的自动化部署系统。
79 0
|
30天前
|
存储 Java
Java 11 的String是如何优化存储的?
本文介绍了Java中字符串存储优化的原理和实现。通过判断字符串是否全为拉丁字符,使用`byte`代替`char`存储,以节省空间。具体实现涉及`compress`和`toBytes`方法,前者用于尝试压缩字符串,后者则按常规方式存储。代码示例展示了如何根据配置决定使用哪种存储方式。
|
2月前
|
Java
在Java中如何将基本数据类型转换为String
在Java中,可使用多种方法将基本数据类型(如int、char等)转换为String:1. 使用String.valueOf()方法;2. 利用+运算符与空字符串连接;3. 对于数字类型,也可使用Integer.toString()等特定类型的方法。这些方法简单高效,适用于不同场景。
84 7
|
3月前
|
Java 测试技术 开发者
Java零基础-indexOf(String str)详解!
【10月更文挑战第13天】Java零基础教学篇,手把手实践教学!
70 1
|
3月前
|
安全 Java 测试技术
Java零基础-StringBuffer 类详解
【10月更文挑战第9天】Java零基础教学篇,手把手实践教学!
74 2