当前位置: 首页 > news >正文

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

众所周知:

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

又有一个众所周知:

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

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

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

 

 

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

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

 

再度聚焦:

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

但是又细眼一看? 

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

 这样做的原因大家都知道,就是重新开辟一波新的空间,这样防止 在后续修改传入的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());

    }

看一下效果:

 

 

好了,该篇就到此。 

相关文章:

  • JAVA 将日期字符串 月份不足10月进行补0操作
  • Springboot Quartz定时任务的动态调度使用,实战详解
  • Springboot 跟着我了解下 事务 @Transactional 默认方式 Propagation.REQUIRED
  • Springboot 全局日期格式化,只需要几行小代码
  • springboot 上传文件设置文件大小限制
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • Springboot 自定义注解+AOP简单实例介绍
  • Java 将Map的toString格式字符串转为 Map
  • Java 细品 重写equals方法 和 hashcode 方法
  • Java 对象的克隆Clone和必须了解的浅拷贝与深拷贝
  • Java i++ 与 ++i
  • Java try 与 finally 对于返回值的影响
  • 手撕一道算法题 在你面前有一个n阶的楼梯,你一步只能上1阶或2阶。请问,当N=11时,你可以采用多少种不同的方式爬完这个楼梯();当N=9时呢?
  • Springboot 整合tk-mybatis , 妈妈,我再也不想敲CRUD的代码了!
  • 【硬着头皮】你还在用size来判断集合是否为空?
  • Babel配置的不完全指南
  • CSS 提示工具(Tooltip)
  • Hibernate【inverse和cascade属性】知识要点
  • Java教程_软件开发基础
  • JS基础之数据类型、对象、原型、原型链、继承
  • js正则,这点儿就够用了
  • js中的正则表达式入门
  • MySQL QA
  • Redis中的lru算法实现
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • Vue组件定义
  • web标准化(下)
  • 半理解系列--Promise的进化史
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 突破自己的技术思维
  • 我从编程教室毕业
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • ​如何防止网络攻击?
  • (003)SlickEdit Unity的补全
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (2)MFC+openGL单文档框架glFrame
  • (k8s中)docker netty OOM问题记录
  • (搬运以学习)flask 上下文的实现
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (七)Java对象在Hibernate持久化层的状态
  • (一)Dubbo快速入门、介绍、使用
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • (转载)OpenStack Hacker养成指南
  • .net 4.0发布后不能正常显示图片问题
  • .NET CORE 3.1 集成JWT鉴权和授权2
  • .NET Core 网络数据采集 -- 使用AngleSharp做html解析
  • .net mvc 获取url中controller和action
  • .net 写了一个支持重试、熔断和超时策略的 HttpClient 实例池
  • .net企业级架构实战之7——Spring.net整合Asp.net mvc
  • [ C++ ] template 模板进阶 (特化,分离编译)
  • [20181219]script使用小技巧.txt
  • [Android]如何调试Native memory crash issue
  • [Angular] 笔记 18:Angular Router