java中stirng真的不可改变么?

news2024/11/14 6:21:10

目录

1. 字符数组的私有性和不可变性

2. 没有提供修改内容的方法

3. 共享字符串常量池

4.不可变性的优点

5.结论


🎈边走、边悟🎈迟早会好

 Java 中的 String 对象是不可变的。不可变性意味着一旦创建了一个 String 对象,它的值就不能再被改变。这一特性在 Java 中是通过以下方式实现的:

1. 字符数组的私有性和不可变性

String 类在内部使用一个字符数组来存储字符串的内容。这个字符数组是私有的,并且没有提供修改其内容的方法。

public final class String implements java.io.Serializable, Comparable<String>, CharSequence { 
private final char value[];
 ... 
}

由于 valuefinal,所以一旦分配了数组引用,就不能再改变它指向的数组。但是注意,这并不阻止数组本身的内容被改变(假设能访问到这个数组)。不过,由于它是私有的,并且没有方法暴露它,外部是无法直接修改这个数组的内容。

2. 没有提供修改内容的方法

String 类没有提供任何方法来修改其内容。所有修改 String 对象的方法(例如 concatsubstringreplace 等)都会返回一个新的 String 对象,而不会修改原来的对象。

String s = "Hello"; String t = s.replace('H', 'J');
​​​​​​​ // s 仍然是 "Hello",t 是 "Jello" 

3. 共享字符串常量池

Java 通过字符串常量池来优化 String 对象的存储。当你创建一个字符串字面量时,Java 会先检查常量池中是否已经有一个相同值的字符串对象。如果有,则返回这个对象的引用;如果没有,则创建一个新的字符串对象并放入池中。这进一步增强了 String 对象的不可变性,因为同一个字符串字面量在 JVM 中只有一个实例

String s1 = "Hello"; String s2 = "Hello"; 
​​​​​​​System.out.println(s1 == s2); // 输出 true 

4.不可变性的优点

  1. 线程安全String 对象是不可变的,因此可以在多个线程间安全地共享,不需要同步
  2. 性能优化:由于字符串不可变,Java 可以安全地在字符串常量池中缓存和重用字符串
  3. 安全性:不可变的字符串可以防止不小心或恶意修改,例如在使用字符串作为哈希表的键或在网络传输中。

5.结论

Java 的 String 对象确实是不可变的。这种不可变性是通过类设计、私有字段和缺乏修改方法来实现的,从而提供了许多线程安全性和性能方面的优势。如果需要可变的字符串,可以使用 StringBuilderStringBuffer 类。

示例代码

public class StringImmutability {
    public static void main(String[] args) {
        String s1 = "Hello";
        String s2 = "World";
        
        // s1 和 s2 都是不可变的
        String s3 = s1.concat(s2); // 生成新的字符串 "HelloWorld"
        
        System.out.println("s1: " + s1); // 输出 "Hello"
        System.out.println("s2: " + s2); // 输出 "World"
        System.out.println("s3: " + s3); // 输出 "HelloWorld"
    }
}

通过以上示例,可以看到 s1s2 在调用 concat 方法后仍然保持原样,说明 String 对象是不可变的。

如果想强行改变,可以通过反射进行改变,但不推荐,因为违反了 Java 对 String 类的不可变设计原则,会造成一些安全问题

String str = "Hello tingyi";
System.out.println(str); // Hello tingyi

Field field = String.class.getDeclaredField("value");
field.setAccessible(true);

char[] value = (char[])field.get(str);
value[6] = 'J';
value[7] = 'a';
value[8] = 'v';
value[9] = 'a';
value[10] = '!';
value[11] = '!';
System.out.println(str); // Hello Java!!

 🌟感谢支持 听忆.-CSDN博客

🎈众口难调🎈从心就好

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1915051.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

怎么提高音频声音大小?提高音频声音大小的四种方法

怎么提高音频声音大小&#xff1f;在音频处理和编辑中&#xff0c;增加声音的音量是一个常见的需求&#xff0c;尤其是在确保音频清晰度和听觉效果的同时。调整音频的音量不仅仅是简单地提高音频的响度&#xff0c;它也涉及到如何保持音质的高标准&#xff0c;确保没有失真或削…

STM32智能机器人手臂控制系统教程

目录 引言环境准备智能机器人手臂控制系统基础代码实现&#xff1a;实现智能机器人手臂控制系统 4.1 数据采集模块 4.2 数据处理与控制算法 4.3 通信与网络系统实现 4.4 用户界面与数据可视化应用场景&#xff1a;机器人手臂管理与优化问题解决方案与优化收尾与总结 1. 引言 …

计算机组成原理:408考研|王道|学习笔记II

系列目录 计算机组成原理 学习笔记I 计算机组成原理 学习笔记II 目录 系列目录第四章 指令系统4.1 指令系统4.1.1 指令格式4.1.2 扩展操作码指令格式 4.2 指令的寻址方式4.2_1 指令寻址4.2_2 数据寻址 4.3 程序的机器级代码表示4.3.1 高级语言与机器级代码之间的对应4.3.2 常用…

leetcode--从前序与中序遍历序列构造二叉树

leetcode地址&#xff1a;从前序与中序遍历序列构造二叉树 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c;请构造二叉树并返回其根节点。 示例 1: 输入: preorder [3,9,20,15,…

提升机器视觉与机器学习软件安全性的实践策略

在近几年科技爆发中&#xff0c;机器学习&#xff08;ML&#xff09;和机器视觉&#xff08;MV&#xff09;的结合正在改变各行各业。机器学习通过数据驱动的算法让计算机能够自我学习&#xff0c;而机器视觉赋予计算机识别和理解图像的能力。这种结合使得计算机可以高效地执行…

传统的springboot项目中,如何进行添加自定义静态资源访问路径实现对静态资源的访问?

如何配置可以实现在浏览器中配置路径实现对resource资源路径下的index.html个性化定制访问路径 要在Spring Boot项目中配置使特定前缀访问静态资源&#xff0c;可以在application.yml文件中配置路径映射。以下是一个示例配置&#xff1a; 打开你的application.yml文件&#xf…

【MindSpore学习打卡】应用实践-LLM原理和实践-基于MindSpore实现BERT对话情绪识别

在当今的自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;情绪识别是一个非常重要的应用场景。无论是在智能客服、社交媒体分析&#xff0c;还是在情感计算领域&#xff0c;准确地识别用户的情绪都能够极大地提升用户体验和系统的智能化水平。BERT&#xff08;Bidirec…

C++基础篇(1)

目录 前言 1.第一个C程序 2.命名空间 2.1概念理解 2.2namespace 的价值 2.3 namespace的定义 3.命名空间的使用 4.C的输入输出 结束语 前言 本节我们将正式进入C基础的学习&#xff0c;话不多说&#xff0c;直接上货&#xff01;&#xff01;&#xff01; 1.第一个C程…

2024.7.10作业

完成学生管理系统 1> 使用菜单完成 2> 有学生的信息录入功能&#xff1a;输入学生个数&#xff0c;并将学生的姓名、分数录入 3> 查看学生信息&#xff1a;输出所有学生姓名以及对应的分数 4> 求出学习最好的学生信息&#xff1a;求最大值 5> 按姓名将所有…

vue学习day05-watch侦听器(监视器)、Vue生命周期和生命周期的四个阶段、、工程化开发和脚手架Vue cli

13、watch侦听器&#xff08;监视器&#xff09; &#xff08;1&#xff09;作用&#xff1a;监视数据变化&#xff0c;执行一些业务逻辑或异步操作 &#xff08;2&#xff09;语法&#xff1a; 1&#xff09;简写语法——简单数据类型&#xff0c;直接监视 ① Watch:{ 数…

python reload找不到怎么办

Python 3.0 把 reload 内置函数移到了 imp 标准库模块中。它仍然像以前一样重载文件&#xff0c;但是&#xff0c;必须导入它才能使用。 方法一&#xff1a; from imp import reload reload(module) 方法二&#xff1a; import imp imp.reload(module)

计算机网络之广域网

广域网特点: 主要提供面向通信的服务&#xff0c;支持用户使用计算机进行远距离的信息交换。 覆盖范围广,通信的距离远&#xff0c;需要考虑的因素增多&#xff0c; 线路的冗余、媒体带宽的利用和差错处理问题。 由电信部门或公司负责组建、管理和维护&#xff0c;并向全社会…

基于Booth乘法和Wallace树的乘法器优化思想

基于Booth乘法和Wallace树的快速乘法器 为了理解Booth乘法和Wallace数如何让乘法器变得更快&#xff1a; 先考虑不优化的8位乘法器实现&#xff0c;即8个16位数字累积共进行7次加法运算&#xff0c;可以认为一次16位加法用到16个全加器&#xff0c;则共需要112个全加器件&…

创建React 项目的几种方式

①.react自带脚手架 使用步骤&#xff1a; 1、下载 npm i create-react-app -g 2、创建项目命令&#xff1a; create-react-app 项目名称 ②.Vite构建工具创建react步骤&#xff1a;&#xff08;推荐&#xff09; 方法一&#xff1a; 1、yarn create vite 2、后续根据提示步…

深度动态IP代理 国内动态IP软件哪个好用

想必大家都用过动态IP产品&#xff0c;什么是动态IP&#xff0c;动态IP就是非固定的静态IP地址&#xff0c;短 时间了频繁波动ip地址&#xff0c;就叫动态IP&#xff0c;因为工作需要用到不同的IP&#xff0c;这时就需要动态IP软件。 今天给大家带来一款深度动态IP软件&#xf…

MySQL安全值守常用语句

一、用户权限设置 1、Mysql中用户是如何定义的 用户名主机域 10.0.0.5110.0.0.%%10.0.0.0/255.255.255.0Db01Localhost127.0.0.1 2、用户创建 create user xinjing% identified by 123 3、用户删除 drop user username&#xff1b;username 是要删除的用户名:如 drop user root…

SpringBoot日常:编码规范之import *

前言 日常开发中&#xff0c;我们在编码过程中会经常忽略import 包的问题&#xff0c;我们会使用import语句中的通配符*来引入整个包中的所有类。尽管这样做能够简化代码编写和阅读&#xff0c;但是过度使用import *也会带来一些坏处&#xff0c;本文将探讨这些问题并给出相应…

在Linux下直接修改磁盘镜像文件的内容

背景 嵌入式Linux系统通常在调试稳定后&#xff0c;会对磁盘&#xff08;SSD、NVME、SD卡、TF卡&#xff09;做个镜像&#xff0c;通常是.img后缀的文件&#xff0c;以后组装新设备时&#xff0c;就将镜像文件烧录到新磁盘即可&#xff0c;非常简单。 这种方法有个不便之处&a…

前端面试题41(在JavaScript中,如何实现MVVM的数据绑定?)

在JavaScript中实现MVVM&#xff08;Model-View-ViewModel&#xff09;架构下的数据绑定&#xff0c;主要通过观察者模式、发布/订阅模式和数据劫持等技术来完成。下面我将概述几种常见的实现方式&#xff0c;以及如何在不使用框架的情况下手动实现数据绑定。 使用框架实现数据…

防御笔记第四天(持续更新)

1.状态检测技术 检测数据包是否符合协议的逻辑顺序&#xff1b;检查是否是逻辑上的首包&#xff0c;只有首包才会创建会话表。 状态检测机制可以选择关闭或则开启 [USG6000V1]firewall session link-state tcp ? check Indicate link state check [USG6000V1]firewall ses…