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

String源码深度刨析

 前言

我们将从源码角度深度分析特点,来提升对他们的了解以及设计。

String、StringBuilder、StringBuffer的常见面试题及四大区别可以参考:String、StringBuilder、StringBuffer的四大区别解析


String

public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence {// 用final 修饰不可变的char 数组存放字符串private final char value[];// 缓存 String 的 hash 值private int hash; // Default to 0// 实现序列化的表示private static final long serialVersionUID = -6849794470754667710L;
}

 String 实现了三个接口:

Comparable: 说明 String 实现了比较功能,可以比较大小(按顺序比较单个字符的ASCII码)

Serializable: 说明 String 可以实现序列化

CharSequence: 表示是一个有序字符的序列,因为String的本质是一个char类型数组.


被 final 修饰的 char[]

fianl 修饰变量表示改变量的值一旦被初始化后不可以修改。fianl 不论是修饰变量、参数、方法、类都表示其 是完美的不可以被修改,或者逻辑顺序不能改变是一个基本逻辑实现元素。

 final 的详细讲解可以看final详解

 那为什么这里要用final修饰呢?

被 fianl 修饰就表示不能被继承或者重写修改,String类的设计是Java设计者不希望程序员继承String也就说明String类的最好用法不是继承,而是依赖和关联的关系。

先说被fianl修饰的字符数组

字符串是我们在开发过程中要进程使用的,每一次的创建对象随着次数的增加都会造成资源的大量消耗,导致内存消耗以及庞大的性能开销,为了提高性能,降低内存消耗,提出了字符串共享的方案,在方法区的常量池中保存下创建唯一的字符串去共给不同的类不同的方法以及线程去使用。

再回到这个数组上,字符串共享是解决内存消耗以及性能开销的必然选择,这里还没回答出为什么要被final修饰。共享带来的问题就是安全问题,在多个线程对通同一个字符串访问操作是不确定的,为了保证线程安全并且兼顾内存资源问题最好的办法就是使用fianl修饰。表示禁止修改。

 类为什么也要被fianl修饰?

final修饰的类表示不可以被继承,就是限制多态/限制行为。Java的一大特性就是安全性,如果不被fianl修饰,在使用Sring的时候会有太多的不确定性,每一个方法都围绕char数组展开,如果被继承方法进行了多态,会造成不同的语义或者错误的定义,使得String的行为性不确定,使得String对象的代码将是不安全的,所以设计成不能被继承的,来保证它的绝对安全。也说明了这个类最好的使用方法是依赖和关联,而不是继承。


创建方式以及存储区域

public class Demo1 {public static void main(String[] args) {String s1 = "hello";String s2 = new String("hello");String s3 = "he" + "llo";String s4 = new String("he") + "llo";String s5 = new String("he") + new String("llo");String s6 = new String(s2);String s7 = new String(s6).intern();System.out.println(s1 == s2); //falseSystem.out.println(s1 == s3); //trueSystem.out.println(s4 == s1); //fasleSystem.out.println(s4 == s2); //falseSystem.out.println(s5 == s2); //falseSystem.out.println(s6 == s2); //fasleSystem.out.println(s7 == s1); //true}
}

        我们知道 s1 这种方式创建的对象是在常量池中,并且在栈区直接指向常量池中第一个字符的地址,第二种方式现在常量池中寻找对象如果没有就创建,然后在堆区创建一个对象引用常量池中的位置,再由栈区获取。每一次new对象都会在栈区创建一个新对象,比如 s7 使用了intern方法返回的结果就是 true 这是因为他们其实在常量池的地址都是一样的,但是因为有了堆区的指向,所以不相等,有了intern直接在栈区指向常量池的地址所以就返回了相等。

 

 

相关文章:

String源码深度刨析

前言 我们将从源码角度深度分析特点&#xff0c;来提升对他们的了解以及设计。 String、StringBuilder、StringBuffer的常见面试题及四大区别可以参考&#xff1a;String、StringBuilder、StringBuffer的四大区别解析 String public final class Stringimplements java.io.Se…...

FreeRTOS - 消息队列

一.消息队列的概念及应用消息队列&#xff08;queue&#xff09;&#xff1a;可以在任务与任务间、中断和任务间传递消息&#xff0c;实现任务接收来自其他任务或中断的不固定的消息1.1任务需求1、使用消息队列检测串口输入2、通过串口发送字符串openled1&#xff0c;openled2&…...

怎样正确做 Web 应用的压力测试?

环境 首先环境是非常重要的&#xff0c;需要尽可能跟生产环境靠近。 比方说&#xff0c;使用同样的nginx版本&#xff0c;php的话需要启用fpm&#xff0c;zend-optimizer等等&#xff0c;参数配置也最好跟生产环境保持一致。 当然&#xff0c;php的版本更加需要保持一致&#x…...

php mysql大学生求职招聘资源信息网zkfdzkf67a8

1&#xff0e;系统登录&#xff1a;系统登录是用户访问系统的路口&#xff0c;设计了系统登录界面&#xff0c;包括用户名、密码和验证码&#xff0c;然后对登录进来的用户判断身份信息&#xff0c;判断是管理员用户还是普通用户。 2&#xff0e;系统用户管理&#xff1a;不管是…...

2023上海市“星光计划”职业院校技能大赛 网络安全竞赛试题任务书

2023上海市“星光计划”职业院校技能大赛 网络安全竞赛试题任务书 A模块基础设施设置/安全加固&#xff08;200分&#xff09; 一、项目和任务描述&#xff1a; 假定你是某企业的网络安全工程师&#xff0c;对于企业的服务器系统&#xff0c;根据任务要求确保各服务正常运行&…...

Spring事务源码:创建代理类

参考文章&#xff1a; 《Spring事务源码解析之tx:annotation-driven标签解析》 《Spring 源码解析—事务执行》 参考资料&#xff1a; 《Spring AOP源码&#xff1a;开启注解读取》 《Spring AOP源码2&#xff1a;查找增强器》 《Spring AOP源码3&#xff1a;实现代理》 …...

java14 使用增强的模式匹配切换表达式

野旷天低树&#xff0c;江清月近人。——唐代杜甫《月夜忆舍弟》 使用增强的模式匹配切换表达式(Switch Expressions with Enhanced Pattern Matching) Java 14中引入的“Switch Expressions with Enhanced Pattern Matching”这个功能。 这个功能可以让我们在使用switch cas…...

python【正则表达式】

正则表达式 1.正则的作用 正则表达式式一种可以让复杂的字符串变得简单的工具。 写正则表达式的时候就是用正则符号来描述字符串规则。 2.正则语法 需要导入模块 from re import fullmatch, findall, search2.1.第一类&#xff1a;匹配类符号 1&#xff09;普通字符—在…...

Ubuntu常见系统问题解决方式

Ubuntu常见系统问题解决方式Ubuntu每次开机后提示检测到系统程序出现问题的解决方法Ubuntu循环登陆问题问题描述原因解决方法文件夹打开缓慢Ubuntu启动后GUI界面卡住不动Ubuntu18.04使用过程中常遇到的问题Ubuntu每次开机后提示检测到系统程序出现问题的解决方法 首先&#xf…...

C/C++中的虚拟内存

文章目录一、虚拟内存二、C中的虚拟内存分配模型三、C中的虚拟内存分配模型四、堆区和栈区的区别一、虚拟内存 虚拟内存是一种实现在计算机软硬件之间的内存管理技术&#xff0c;它将程序使用到的内存地址&#xff08;虚拟地址&#xff09;映射到计算机内存中的物理地址&#…...

Qt C++与Python混合编程:补充错误

在提示中&#xff0c;需要引用Python.h&#xff0c;出现错误。 1、找不到Python.h 如果是pro工程&#xff0c;需要在里面配置&#xff1b; INCLUDEPATH /Users/xinnianwang/opt/anaconda3/include LIBS /Users/xinnianwang/opt/anaconda3/lib 如果是CMakeLists.txt需要配…...

2023-04-01:当Go语言遇见FFmpeg视频解码器,使用Go语言改写decode_video.c文件,提升视频解码效率与开发体验。

2023-04-01&#xff1a;当Go语言遇见FFmpeg视频解码器&#xff0c;使用Go语言改写decode_video.c文件&#xff0c;提升视频解码效率与开发体验。 答案2023-04-01&#xff1a; 步骤如下&#xff1a; 1.导入必要的依赖库&#xff0c;包括 fmt、os、unsafe 和其它 FFmpeg 库相关…...

Solidity 学习笔记

主要参考网上资料学习&#xff0c;个人学习笔记有删改&#xff0c;参考出处在文末列出。 0 基础 IDE: remixType Bool: bool public _bool true; 默认false;整型&#xff1a;int、uint、uint256&#xff0c;默认0;地址类型&#xff1a;address&#xff0c;分为 payable 和普…...

ThreadLocal原理

关键点总结&#xff1a; ThreadLocal更像是对其他类型变量的一层包装&#xff0c;通过ThreadLocal的包装使得该变量可以在线程之间隔离和当前线程全局共享。在Thread中有一个threadLocals变量&#xff0c;类型为ThreadLocal.ThreadLocalMap&#xff0c;ThreadLocalMap中key是Th…...

串操作指令详解 MOVS,LODS,STOS,CMPS,SCAS,REP

指令包括&#xff1a;MOVS&#xff0c;LODS&#xff0c;STOS&#xff0c;CMPS&#xff0c;SCAS&#xff0c;REP 串的概念&#xff1a;串是连续存放再内存中的字节块或字块。每个串有一个起始地址和长度&#xff0c; 待操作的数据串称为源串&#xff0c;目的地址称为目标串 目录…...

Java实现判断素数

1 问题 判断101-200之间有多少个素数&#xff0c;并输出所有素数。 2 方法 package homework04; public class Test05 { public static void main(String[] args) { for (int i 101; i < 201; i) { boolean flag true; for (int j 2; j…...

PHP初级教程------------------(2)

目录 运算符 赋值运算符 算术运算符 比较运算符 逻辑运算符 连接运算符 错误抑制符 三目运算符 自操作运算符 ​编辑 计算机码 位运算符 运算符优先级 流程控制 控制分类 顺序结构 分支结构 If分支 ​ Switch分支 循环结构 For循环 while循环 do-while循环 循环控制 ​ …...

【SQL开发实战技巧】系列(三十五):数仓报表场景☞根据条件返回不同列的数据以及Left /Full Join注意事项

系列文章目录 【SQL开发实战技巧】系列&#xff08;一&#xff09;:关于SQL不得不说的那些事 【SQL开发实战技巧】系列&#xff08;二&#xff09;&#xff1a;简单单表查询 【SQL开发实战技巧】系列&#xff08;三&#xff09;&#xff1a;SQL排序的那些事 【SQL开发实战技巧…...

springBoot自动配置过程介绍

什么是自动配置 以前整合spring mybatis框架时候&#xff0c;需要加很多的bean, 比如说sqlSessionFactory等等 现在springboot帮我们干了&#xff0c;我们只需要引入对应的starter就可以了。 springBoot可以帮我们配置好了一些bean. 如mysql, mogondb相关操作等等&#xff…...

PostgreSQL最后的救命稻草 — pg_resetwal

pg_resetwal— 重置 PostgreSQL 数据库集群的预写日志和其他控制信息 适用版本&#xff1a;PostgreSQL 12/13/14/15语法 pg_resetwal [ -f | --force ] [ -n | --dry-run ] [option...] [ -D | --pgdata ]datadir描述pg_resetwal清除预写日志 WAL&#xff0c;并可选地重置pg_c…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具

第2章 虚拟机性能监控&#xff0c;故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令&#xff1a;jps [options] [hostid] 功能&#xff1a;本地虚拟机进程显示进程ID&#xff08;与ps相同&#xff09;&#xff0c;可同时显示主类&#x…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

深入理解Optional:处理空指针异常

1. 使用Optional处理可能为空的集合 在Java开发中&#xff0c;集合判空是一个常见但容易出错的场景。传统方式虽然可行&#xff0c;但存在一些潜在问题&#xff1a; // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...

Qt 事件处理中 return 的深入解析

Qt 事件处理中 return 的深入解析 在 Qt 事件处理中&#xff0c;return 语句的使用是另一个关键概念&#xff0c;它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别&#xff1a;不同层级的事件处理 方…...

MySQL体系架构解析(三):MySQL目录与启动配置全解析

MySQL中的目录和文件 bin目录 在 MySQL 的安装目录下有一个特别重要的 bin 目录&#xff0c;这个目录下存放着许多可执行文件。与其他系统的可执行文件类似&#xff0c;这些可执行文件都是与服务器和客户端程序相关的。 启动MySQL服务器程序 在 UNIX 系统中&#xff0c;用…...