iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >String的不可变是因为Final 吗
  • 313
分享到

String的不可变是因为Final 吗

2024-04-02 19:04:59 313人浏览 泡泡鱼
摘要

这篇文章主要讲解了“String的不可变是因为Final 吗”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“String的不可变是因为Final 吗”吧!St

这篇文章主要讲解了“String的不可变是因为Final 吗”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“String的不可变是因为Final 吗”吧!

String 为啥不可变?因为 String 中的 char 数组被 final 修饰。这套回答相信各位已经背烂了,But 这并不正确!

  • 面试官:讲讲 String、StringBuilder、StringBuffer 的区别

  • 我:String 不可变,而 StringBuilder 和 StringBuffer 可变,叭叭叭 ......

  • 面试官:String 为什么不可变?

  • 我:String 被 final 修饰,这说明 String 不可继承;并且String 中真正存储字符的地方是 char 数组,这个数组被 final  修饰,所以 String 不可变

  • 面试官:String 的不可变真的是因为 final 吗?

  • 我:是.....是的吧

  • 面试官:OK,你这边还有什么问题吗?

  • 我:卒......

什么是不可变?

《Effective Java》中对于不可变对象(Immutable  Object)的定义是:对象一旦被创建后,对象所有的状态及属性在其生命周期内不会发生任何变化。这就意味着,一旦我们将一个对象分配给一个变量,就无法再通过任何方式更改对象的状态了。

String 不可变的表现就是当我们试图对一个已有的对象 "abcd" 赋值为 "abcde",String 会新创建一个对象:

String的不可变是因为Final 吗

String 为什么不可变?

String 用 final 修饰 char 数组,这个数组无法被修改,这么说确实没啥问题。

String的不可变是因为Final 吗

但是!!!这个无法被修改仅仅是指引用地址不可被修改(也就是说栈里面的这个叫 value 的引用地址不可变,编译器不允许我们把 value  指向堆中的另一个地址),并不代表存储在堆中的这个数组本身的内容不可变。举个例子:

String的不可变是因为Final 吗

如果我们直接修改数组中的元素,是完全 OK 的:

String的不可变是因为Final 吗

那既然我们说 String 是不可变的,那显然仅仅靠 final 是远远不够的:

1)首先,char 数组是 private 的,并且 String 类没有对外提供修改这个数组的方法,所以它初始化之后外界没有有效的手段去改变它;

2)其次,String 类被 final 修饰的,也就是不可继承,避免被他人继承后破坏;

3)最重要的!是因为 Java 作者在 String 的所有方法里面,都很小心地避免去修改了 char 数组中的数据,涉及到对 char  数组中数据进行修改的操作全部都会重新创建一个 String 对象。你可以随便翻个源码看看来验证这个说法,比如 substring 方法:

String的不可变是因为Final 吗

为什么要设计成不可变的呢?

1)首先,字符串常量池的需要。

我们来回顾一下字符串常量池的定义:大量频繁的创建字符串,将会极大程度的影响程序的性能。为此,JVM  为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化

  • 为字符串开辟了一个字符串常量池 String Pool,可以理解为缓存

  • 创建字符串常量时,首先检查字符串常量池中是否存在该字符串

  • 若字符串常量池中存在该字符串,则直接返回该引用实例,无需重新实例化;若不存在,则实例化该字符串并放入池中。

如下面的代码所示,堆内存中只会创建一个 String 对象:

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

String的不可变是因为Final 吗

假设 String 允许被改变,那如果我们修改了 str2 的内容为 Good,那么 str1 也会被修改,显然这不是我们想要看见的结果。

2)另外一点也比较容易想到,String 被设计成不可变就是为了安全

作为最基础最常用的数据类型,String 被许多 Java 类库用来作为参数,如果 String 不是固定不变的,将会引起各种安全隐患。

举个例子,我们来看看将可变的字符串 StringBuilder 存入 HashSet 的场景:

String的不可变是因为Final 吗

我们把可变字符串 s3 指向了 s1 的地址,然后改变 s3 的值,由于 StringBuilder 没有像String 那样设计成不可变的,所以 s3  就会直接在 s1 的地址上进行修改,导致 s1 的值也发生了改变。于是,糟糕的事情发生了,HashSet 中出现了两个相等的元素,破坏了 HashSet  的不包含重复元素的原则。

另外,在多线程环境下,众所周知,多个线程同时想要修改同一个资源,是存在危险的,而String  作为不可变对象,不能被修改,并且多个线程同时读同一个资源,是完全没有问题的,所以 String 是线程安全的。

String 真的不可变吗?

想要改变 String 无非就是改变 char 数组 value 的内容,而 value 是私有属性,那么在 Java  中有没有某种手段可以访问类的私有属性呢?

没错,就是反射,使用反射可以直接修改 char 数组中的内容,当然,一般来说我们不这么做。

看下面代码:

String的不可变是因为Final 吗

总结

总结来说,并不是因为 char 数组是 final 才导致 String 的不可变,而是为了把 String 设计成不可变才把 char 数组设置为  final 的。下面是一些创建不可变对象的简单策略,当然,也并非所有不可变类都完全遵守这些规则:

  • 不要提供 setter 方法(包括修改字段的方法和修改字段引用对象的方法);

  • 将类的所有字段定义为 final、private 的;

  • 不允许子类重写方法。简单的办法是将类声明为 final,更好的方法是将构造函数声明为私有的,通过工厂方法创建对象;

  • 如果类的字段是对可变对象的引用,不允许修改被引用对象。

感谢各位的阅读,以上就是“String的不可变是因为Final 吗”的内容了,经过本文的学习后,相信大家对String的不可变是因为Final 吗这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: String的不可变是因为Final 吗

本文链接: https://www.lsjlt.com/news/68001.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • String的不可变是因为Final 吗
    这篇文章主要讲解了“String的不可变是因为Final 吗”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“String的不可变是因为Final 吗”吧!St...
    99+
    2024-04-02
  • Java中String是不可变的吗
    这篇文章主要介绍“Java中String是不可变的吗”,在日常操作中,相信很多人在Java中String是不可变的吗问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中String是不可变的吗”的疑惑有所...
    99+
    2023-06-27
  • Java中的String为什么是不可变的
    这篇文章主要介绍“Java中的String为什么是不可变的”,在日常操作中,相信很多人在Java中的String为什么是不可变的问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java中的String为什么是不...
    99+
    2023-06-17
  • 分析Java中为什么String不可变
    目录常量池便利安全引申问题String在Java中的【引用传递】常量池 Java中我们创建String对象有两种基本方法。 String str1 = "zxhtom"; Str...
    99+
    2024-04-02
  • 基于String不可变字符与StringBuilder可变字符的效率问题
    String与StringBuilder的效率 ‍1.如果需知要拼接的内容比较道少 不可变,拼接的多会产生多个新的对象,十分的耗费内存空间和程序执行效率 String...
    99+
    2024-04-02
  • python的可变和不可变数据类型是什么
    这篇文章主要讲解了“python的可变和不可变数据类型是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“python的可变和不可变数据类型是什么”吧!不可变数据类型python中不可变数据...
    99+
    2023-06-02
  • 分析JDK中String的存储区与不可变性
    这篇文章主要介绍“分析JDK中String的存储区与不可变性”,在日常操作中,相信很多人在分析JDK中String的存储区与不可变性问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”分析JDK中String的存储...
    99+
    2023-06-02
  • Java中的String对象不可改变的特性有哪些
    Java中的String对象不可改变的特性有哪些?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。1. String对象不可改变的特性下图显示了如下代码运行的过程:...
    99+
    2023-05-31
    java string ava
  • 揭秘 Golang 字符串背后的秘密:可变还是不可变
    go 字符串不可变,但可以通过指针修改。1. 字符串是值类型,分配新变量时创建新值。2. 指针可以指向字符串并修改其内容。3. 字符串拼接创建新副本,不影响原字符串。 深入浅出:揭开 ...
    99+
    2024-04-08
    字符串 golang
  • php数组中的元素可不可以是变量
    今天小编给大家分享一下php数组中的元素可不可以是变量的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。PHP数组中的元素可以是...
    99+
    2023-07-02
  • c++中log函数的底数可以是变量吗
    非常抱歉,由于您没有提供文章标题,我无法为您生成一篇高质量的文章。请您提供文章标题,我将尽快为您生成一篇优质的文章。...
    99+
    2024-05-14
  • java如何证明字符串是不可变的
    这篇文章主要介绍了java如何证明字符串是不可变的,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。如何证明字符串是不可变的字符串不可变的这个事我曾写过两篇文章,写到最后我都要吐...
    99+
    2023-06-27
  • Vue不能检测数组变动的原因是什么
    小编给大家分享一下Vue不能检测数组变动的原因是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!问题来源:https://se...
    99+
    2024-04-02
  • windows默认网关不可用的原因是什么
    这篇文章主要介绍“windows默认网关不可用的原因是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“windows默认网关不可用的原因是什么”文章能帮助大家解决问题。默认网关不可用的原因:主要可...
    99+
    2023-07-01
  • python函数的默认参数为什么不可以定义可变类型
    这篇文章主要介绍“python函数的默认参数为什么不可以定义可变类型”,在日常操作中,相信很多人在python函数的默认参数为什么不可以定义可变类型问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”python函...
    99+
    2023-06-29
  • 华为云服务器续费优惠活动是真的吗吗安全吗可靠吗
    华为云服务器续费优惠活动的具体情况可能因地区、时间、服务器硬件配置和价格等因素而不同,因此建议您先查询当地华为云官网或相关宣传资料以获取更多信息。此外,如果您选择购买华为云服务器,建议您确认其是否与华为终端设备有关联,以确保您的数据不被泄露...
    99+
    2023-10-26
    华为 优惠活动 续费
  • Bash 是 Python 学习中必不可少的工具吗?
    随着人工智能的飞速发展,越来越多的人开始学习编程语言,其中 Python 是最受欢迎的一种。Python 有着简单易学、功能强大、开源免费等优点,因此在人工智能领域得到了广泛应用。然而,学习 Python 时,我们是否需要掌握其他工具呢?...
    99+
    2023-08-02
    学习笔记 laravel bash
  • php中相同的值可能不等于的原因是什么
    这篇文章主要介绍“php中相同的值可能不等于的原因是什么”,在日常操作中,相信很多人在php中相同的值可能不等于的原因是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”php中相同的值可能不等于的原因是什么...
    99+
    2023-07-05
  • String hashCode方法选择数字31作为乘子的原因是什么
    本篇内容主要讲解“String hashCode方法选择数字31作为乘子的原因是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“String hashCode方法选择数字31作为乘子的原因是什...
    99+
    2023-06-15
  • 华为云服务器续费优惠活动是真的吗安全吗可靠吗
    华为云服务器续费优惠活动的具体情况可能因地区、时间、服务器硬件配置和价格等因素而不同,因此该活动是否真的值得购买取决于您的个人购买偏好和需要。同时,我们强烈建议您仔细阅读任何优惠政策和条款,并进行充分的了解和评估。此外,我们也建议您选择有信...
    99+
    2023-10-26
    华为 优惠活动 续费
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作