String类为什么被设计成不可变类

1.享元模式:

1.共享元素模式,也就是说:一个系统中如果有多处用到了相同的一个元素,那么我们应该只存储一份此元素,而让所有地方都引用这一个元素。

2.Java中String就是根据享元模式设计的,而那个存储元素的地方就叫做 “字符串常量池——String Pool”。

2.享元模式分析:

int x = 10;

String y = “hello”;

1). 首先,10 和 “hello”会在经过javac(或者其他编译器)编译过后变为Class文件中constant_pool table的内容。

2). 当我们的程序运行时,也就是说JVM运行时,每个Class constant_pool table中的内容会被加载到JVM内存中的方法区中各自Class的Runtime Constant Pool。

3). 一个没有被String Pool包含的Runtime Constant Pool中的字符串(这里是”hello”)会被加入到String Pool中(HosSpot使用hashtable引用方式),步骤如下:

一是:在Java Heap中根据”hello”字面量create一个字符串对象

二是:将字面量”hello”与字符串对象的引用在hashtable中关联起来,键 – 值 形式是:”hello” = 对象的引用地址。

4). 当一个新的字符串出现在Runtime Constant Pool 中时怎么判断需不需要在Java Heap中创建新对象呢?

策略是这样:

会先去根据equals来比较Runtime Constant Pool 中的这个字符串是否和String Pool中某一个是相等的(也就是找是否已经存在),

如果有那么就不创建,直接使用其引用;

如此,就实现了享元模式,提高的内存利用效率。

3.设计成不可变类的好处:

优点:
1.效率:例如字符串常量池,字符串常量池可以将一些字符常量放在常量池中重复使用,避免每次都重新创建相同的对象、节省存储空间。

但如果字符串是可变的,此时相同内容的String还指向常量池的同一个内存空间,当某个变量改变了该内存的值时,其他遍历的值也会发生改变。

2.安全性:不可变对象天生是线程安全的,在不同线程共享对象,不需要同步机制,因为对象的值是固定的。

缺点:

资源开销,对象需要频繁的修改属性,则每一次修改都会新创建一个对象,产生大量的资源开销。

常见的不可变类: String Integer Long等类型。

4. 如何设计一个不可变类:

  1. 类使用final修饰符修饰,保证类不能被继承。

如果类可以被继承会破坏类的不可变性机制,只要继承类覆盖父类的方法并且继承类可以改变成员变量值,那么一旦子类以父类的形式出现时,不能保证当前类是否可变。

2.类的成员变量都应该是private final的,保证成员变量不可改变。

3.任何获取/修改属性的方法都不应作用于属性本身。

不提供修改成员变量的方法,例如setter方法。

getter方法不能返回对象本身,要返回对象的拷贝,防止对象外泄。

修改对象的属性时要返回新对象

4.对成员变量的初始化通过构造器进行,并进行深拷贝。

如果使用传入的参数直接赋值,则传递的只是引用,仍然可以通过外部变量改变它的值。

5.Demo:

1.先定义一个名为str引用变量,放入到栈中。

2.然后检查字符串池中是否存在内容为”hello”的对象。

3.不存在,则在堆中创建一个指定的对象,并让str引用指向该对象(然后需要从堆中复制到常量池中,否则导致浪费池的空间)

4.存在,则从常量池中拷贝一份到堆中(然后返回堆中的地址,让栈中的str对象指向该地址,进行关联)

注意:对字符串进行赋值时,如果右操作数含有一个或一个以上的字符串引用时,则会在堆中建立一个字符串对象,返回引用;如String str2=str1+ “abc”;

Original: https://www.cnblogs.com/pfzhang18/p/16114271.html
Author: 2022年总冠军gogogo
Title: String类为什么被设计成不可变类

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/571243/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 【Unity Shader学习笔记】Unity光照基础-漫反射光照

    本代码只适用于平行光。 1、逐顶点漫反射光照 1.1漫反射光照原理 1.2代码实现 在Properties语义块中声明一个漫反射颜色属性 Properties { //&#…

    Java 2023年6月8日
    085
  • windows 2003 不同网段 无法 文件共享 VSS设置

    网上搜索了很多解答,比如设置VPN, 修改ETC表, 自己也设置了VPN,确实可以,设置的过程需要关闭WINDOWS自带的防火墙,让我觉得不太习惯。 就研究了下防火墙的例外项 点击…

    Java 2023年6月14日
    083
  • 学生管理系统 C++课设

    #include #include #include<string.h> #include using namespace std; /////////////////…

    Java 2023年6月5日
    086
  • spring cloud alibaba 组件版本关系 以及 毕业版本依赖关系

    Spring Cloud Alibaba VersionSentinel VersionNacos VersionRocketMQ VersionDubbo VersionSeat…

    Java 2023年6月7日
    070
  • idea远程debug

    1,打包项目 把项目打成jar 2,配置idea远程调试 我设置的是本地调试,远程服务器设置为远程的服务器和端口即可。 3, 服务器启动项目 启动项目: java -agentli…

    Java 2023年6月5日
    081
  • 蓝叠、逍遥、夜游模拟器,虚拟机与hyper-v兼容问题解决,w10家庭版关闭hyper-v,华为matebook

    解决方法最后,我在测试蓝叠的时候,还是hyper-v的问题。然后我进入windows安全中心->设备安全性->内核隔离->关闭,然后再运行蓝叠,然后就成功了,什么…

    Java 2023年5月30日
    078
  • ThreadLocal

    1. 简介 _ThreadLocal_是Thread的局部变量,用于编写多线程程序,这种变量在多线程环境下访问时能够保证各个线程里变量的独立性。 能干什么: 存储数据 & …

    Java 2023年6月7日
    077
  • Java如何对一个对象进行深拷贝?

    深拷贝实现代码:https://github.com/wudashan/java-deep-copy 深拷贝实现代码:https://github.com/wudashan/jav…

    Java 2023年5月29日
    090
  • 上传图像

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年6月6日
    0105
  • 大批量数据的插入优化的小细节

    今天在测试将elasticsearch中的20万条数据迁移到MySQL中时,总感觉速度比较慢,尝试了好多方法,比如网上都说的: public void batchSave(List…

    Java 2023年6月7日
    084
  • 【Java】命令

    jar 一. 参数类型说明 1. 标准参数(-) 2. 非标准参数(-X) 3. 非Stable参数(-XX) 4. 程序参数(–) 5. 环境变量(-D) 二. 使用…

    Java 2023年5月29日
    090
  • IDEA 去除 mybatis.xml 文件黄色警告

    默认情况下在 mybatis 的 xml 文件中,IDEA 会报如下警告 去除黄色背景的警告,步骤如下 找到 设置 , Editor,Inspections,SQL 去除 No d…

    Java 2023年5月30日
    078
  • Yum安装,Linux自带Python卸载 安装

    1.卸载python(防止未卸载干净) 2.卸载yum 3.验证是否删除干净 4.安装python和yum 下面提供两个centos的版本 一个是7.5.1804的 一个是7.8….

    Java 2023年6月13日
    087
  • Java学习第二周—数据结构和集合框架

    Java 数据结构 Java工具包提供了强大的数据结构。在Java中的数据结构主要包括以下几种接口和类: 枚举(Enumeration) 位集合(BitSet) 向量(Vector…

    Java 2023年6月9日
    077
  • 基于微前端qiankun的多页签缓存方案实践

    作者:vivo 互联网前端团队- Tang Xiao 本文梳理了基于阿里开源微前端框架qiankun,实现多页签及子应用缓存的方案,同时还类比了多个不同方案之间的区别及优劣势,为使…

    Java 2023年6月15日
    0109
  • Oracle扩展表空间

    Oracle扩展表空间 前言: Oracle表空间扩展最大为32G,目前我还未找到可以打破限制的办法。 一、查看表空间信息和使用情况 查看表空间的名字及文件所在位置 — &amp…

    Java 2023年6月8日
    0140
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球