【Java】/* 浅谈String(下) */

目录

一、字符串的不可变性

二、字符串的修改

三、StringBuilder和StringBuffer 

四、面试题


一、字符串的不可变性

1. 如上图所示,String类的是被final修饰的类(不能被继承),成员变量value值是一个被final修饰的字节型数组。

2. 以下图代码为例,字符串的不可变性在讲某字符串变量被重新赋值新的字符串常量值时,并不是将原本的字符串修改成了新的字符串,而是会在常量池中查找是否有"hello"对象,如果有仍然使str引用指向字符串常量池中的“hello”对象,如果没有则会在字符串常量池中创建一个新的对象,然后让str引用指向这个新的对象

3. 为什么不直接修改常量池中“hello”对象的value值呢,反而要采用创建新对象的方式?

答:① 首先我们得了解一下被final修饰的数组意味着什么。

没被final修饰前的数组引用:

被final修饰后的数组引用:下图中当数组被final修饰后array引用的值不能够被修改了(array引用不能指向一个新的数组对象),但数组每个元素的内容是可变的。

② 依照第①点得出的结论,也就是说我们不可以更改value引用的值,但是可以更改value数组每个元素的内容。此时有人就会说,那我们直接去更改value数组每个元素的内容就好了呀。但是观察String类的原码可以发现,成员变量value被private修饰了,且编译器并没有提供getter 和 setter方法,private这个修饰符也是无法被修改的,也就是说我们没办法拿到value引用所指向的对象,通过数组名[]去更改value数组中的值,更不可能去更改value引用的值,综上str="world"类似的赋值,编译器并没有采用改常量池中“hello”对象的value值,反而是采用了创建新对象的方式。

4. 纠正:有些人说:字符串不可变是因为其内部保存字符的数组被final修饰了,因此不能改变。 这种说法是错误的,不是因为String类自身,或者其内部value被final修饰而不能被修改。 final修饰类表明该类不想被继承,final修饰引用类型表明该引用变量不能引用其他对象,但是其引用对象中的内容是可以修改的。字符串的不可变是因为其内部保存字符的数组被private final修饰,且String类中没有提供getter 和 setter方法,private这个修饰符也无法被修改使得我们无法修改value引用的值 和 value引用所指向对象的值所导致的。

补充:Java中可以通过一种叫反射的机制来获取到被封装的字段,在数组结构的最后会讲到,埋坑🕳。

5. 为什么 String 要设计成不可变的?(不可变对象的好处是什么?) (选学)

    ①. 方便实现字符串对象池. 如果 String 可变, 那么对象池就需要考虑写时拷贝的问题了.

    ②. 不可变对象是线程安全的.

    ③. 不可变对象更方便缓存 hash code, 作为 key 时可以更高效的保存到 HashMap 中.

二、字符串的修改

1. 依据字符串的不可变形,也就是说下图代码并不属于对字符串本身进行修改。

2. 上述代码的底层等效代码:

   也就是说如果我么写出了一个这样的代码:

在代码的底层每次拼接都会new 一个StringBuilder对象,调用stringBuilder.append()方法,这样的代码非常耗费资源。修改代码(使用StringBuilder实现字符串的拼接):

3. 注意:String和StringBuilder类不能直接转换。如果要想互相转换,可以采用如下原则:

    ① String变为StringBuilder: 利用StringBuilder的构造方法或append()方法。

    ② StringBuilder变为String: 调用toString()方法。

4. 总之,尽量避免对String的直接修改或拼接,因为在这过程中会额外创建很多的对象消耗资源,因此如果某字符串变量在使用过程中会进行修改或拼接操作建议尽量使用StringBuffer类或者StringBuilder类。

三、StringBuilder和StringBuffer 

1. StringBuilder和StringBuffer类的常见使用方式是一样的:

2. 对StringBuilder和StringBuffer对象的修改/拼接都是在对象本身进行修改/拼接 (和String类相反)

3. StringBuilder和StringBuffer的区别: 单线程用StringBuilder, 多线程用StringBuffer。

四、面试题

1. String、StringBuffer、StringBuilder的区别?

    ① String和StringBuffer、StringBuilder相比,String的内容不可修改,而StringBuffer、StringBuilder的内容可修改,且含有一些String没有的方法。

    ② StringBuffer、StringBuilder这两个类大部分功能是相同的,区别在于StringBuffer被synchronized修饰r采用同步处理,属于线程安全操作,通常在多线程中会使用到,而StringBuilder未采用同步处理,属于线程不安全操作。

2. 以下总共创建了多少个String对象【前提不考虑常量池之前是否存在】(答案:8个)

    String str = new String("ab"); // 会创建2个对象

    String str = new String("a") + new String("b"); // 会创建6个对象(注意:调用toString方法,toString方法底层也会new一个对象)

 本篇已完结 ......

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

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

相关文章

JavaWeb笔记_Session

Session概述 Session是一种在服务端记录用户会话信息的技术 Session的创建和获取 /*** HttpServletRequest对象中的方法:* public HttpSession getSession()* 如果当前服务端没有session,那就在服务端新建一个session对象* 如果在服务端有这个session,那么就直…

Java企业微信服务商代开发获取AccessToken示例

这里主要针对的是企业微信服务商代开发模式 文档地址 可以看到里面大致有三种token,一个是服务商的token,一个是企业授权token,还有一个是应用的token 这里面主要有下面几个参数 首先是服务商的 corpid 和 provider_secret ,这个可…

C中字符串处理学习笔记

C中字符串处理学习笔记 目录 C中字符串处理学习笔记1. 字符串长度相关函数1.1 strlen函数1.2 strnlen函数 2. 字符串复制、设置相关函数2.1 strcpy函数2.2 strncpy函数2.3 strlcpy函数2.4 strcat函数2.5 strncat函数2.6 strlcat函数2.7 sprintf函数2.8 snprintf函数2.9 asprint…

mysql常用函数五大类

mysql常用函数 1. 第一类:数值函数1.1 圆周率pi的值1.2 求绝对值1.3 返回数字的符号1.4 开平方,根号1.5 求两个数的余数1.6 截取正数部分1.7 向上取整数1.8 向下取整数1.9 四舍五入函数1.10 随机数函数1.11 数值左边补位函数1.12 数值右边补位函数1.13 次…

83. UE5 RPG 实现属性值的设置

在前面,我们实现了角色升级相关的功能,在PlayerState上记录了角色的等级和经验值,并在变动时,通过委托广播的形式向外广播,然后在UI上,通过监听委托的变动,进行修改等级和经验值。 在这一篇里&a…

鸿蒙开发仓颉语言【Hyperion: 一个支持自定义编解码器的TCP通信框架】组件

Hyperion: 一个支持自定义编解码器的TCP通信框架 特性 支持自定义编解码器高效的ByteBuffer实现,降低请求处理过程中数据拷贝自带连接池支持,支持连接重建、连接空闲超时易于扩展,可以积木式添加IoFilter处理入栈、出栈消息 组件 hyperio…

Mongodb的通配符索引

学习mongodb,体会mongodb的每一个使用细节,欢迎阅读威赞的文章。这是威赞发布的第95篇mongodb技术文章,欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题,欢迎在文章下面点个赞,或者关…

代理协议解析:如何根据需求选择HTTP、HTTPS或SOCKS5?

代理IP协议是一种网络代理技术,可以实现隐藏客户端IP地址、加速网站访问、过滤网络内容、访问内网资源等功能。常用的IP代理协议主要有Socks5代理、HTTP代理、HTTPS代理这三种。代理IP协议主要用于分组交换计算机通信网络的互联系统中使用,只负责数据的路…

python-基础篇-字符串-是什么

文章目录 定义一:所谓字符串,就是由零个或多个字符组成的有限序列,在Python程序中,如果我们把单个或多个字符用单引号或者双引号包围起来,就可以表示一个字符串。字符串和常用数据结构使用字符串 通过多个角度的定义了…

开局一个启动器:从零开始入坑ComfyUI

前几天刷某乎的时候看到了一位大佬写的好文,可图 IP-Adapter 模型已开源,更多玩法,更强生态! - 知乎 (zhihu.com) 久闻ComfyUI大名,决定试一下。这次打算不走寻常路,不下载现成的一键包了,而是…

let、var、const 的区别 --js面试题

作用域 ES5中的作用域有:全局作用域、函数作用域,ES6中新增了块级作用域。块作用域由 { } 包括,if 语句和 for 语句里面的 { } 也属于块作用域。 var 1.没有块级作用域的概念,但具有函数全局作用域、函数作用域的概念 {var a …

【凸优化】二次约束二次规划(QCQP)问题转化为二阶锥规划(SOCP)

二次约束二次规划(QCQP)问题的SOCP形式转化 1. 问题描述 1.1. QCQP的一般形式: min ⁡ 1 2 x ⊤ Q 0 x c ⊤ x s . t . x ⊤ Q i x a i ⊤ x ≤ b i , i 1 , … , m \begin{aligned} \min \quad &\frac{1}{2}\mathbf{x}^{\top}\math…

移除链表元素 - 力扣(LeetCode)

203. 移除链表元素 - 力扣(LeetCode) /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* removeElements(struct ListNode* head, int val) {struct ListNode* cur hea…

ubuntu c++ nginx ffmpeg 推流海康摄像头视频

环境:Ubuntu18.04 使用到的库:nginx,ffmpeg 外设:海康任一款摄像头,分辨率:1280*720 Ubuntu c 海康sdk获取原始码流,使用ffmpeg编码推流到nginx服务器,使用vlc即可拉到rtmp图像&a…

别再只知道埋头苦学python了!!学了python后月入1w不在话下,不准你还不知道!!!

在Python接单的过程中,掌握一些技巧、注意相关事项以及选择合适的接单平台是非常重要的 一、Python接单要注意哪些 报酬问题:在接单前,务必明确客户所说的报酬是税前还是税后,以避免后期产生纠纷。时间管理:不要与客户…

Nginx 如何处理 WebSocket 连接?

🍅关注博主🎗️ 带你畅游技术世界,不错过每一次成长机会! 文章目录 Nginx 如何处理 WebSocket 连接?一、WebSocket 连接简介二、Nginx 处理 WebSocket 连接的基本原理三、配置 Nginx 支持 WebSocket 连接四、Nginx 中的…

【启明智显分享】甲醛检测仪HMI方案:ESP32-S3方案4.3寸触摸串口屏,RS485、WIFI/蓝牙可选

今年,“串串房”一词频繁引发广大网友关注。“串串房”,也被称为“陷阱房”“贩子房”——炒房客以低价收购旧房子或者毛坯房,用极度节省成本的方式对房子进行装修,之后作为精修房高价租售,因甲醛等有害物质含量极高&a…

LeetCode-day23-3098. 求出所有子序列的能量和

LeetCode-day23-3098. 求出所有子序列的能量和 题目描述示例示例1:示例2:示例3: 思路代码 题目描述 给你一个长度为 n 的整数数组 nums 和一个 正 整数 k 。 一个 子序列的 能量 定义为子序列中 任意 两个元素的差值绝对值的 最小值 。 请…

“从爱好者到职业画师:一位AI绘画践行者的赚钱实战秘籍“

🎨 【引子:AI绘画:艺术与科技的交汇】 在数字化浪潮席卷全球的今天,人工智能技术以其颠覆性的力量,正悄然改写着艺术创作的传统版图。当AI与绘画碰撞交融,诞生出一种全新的艺术形式——AI绘画。它不仅是科…

别只盯着苹果了,华为Mate70也有AI技术,听说效果让人直接惊呼

随着人工智能技术的不断进步,智能手机行业也迎来了前所未有的变革。苹果、三星等国际知名手机厂商纷纷在新品发布会上重点展示其手机的AI技术,而华为作为中国科技的领军企业,其在AI领域的成就同样不容小觑。 华为Mate系列作为其旗舰系列&…