带你一文深入认识Java String类
作者:萝诗粉 发布时间:2023-10-15 10:55:54
前言
String 类在Java中是很常用的类,很重要的类,在后续的学习中经常会用到,是后续学习的基础
一、认识String
1.JDK中的String
首先我们看看JDK中的String类源码,它实现了很多接口,可以看到String类被final修饰了,这就说明String类不可以被继承,String不存在子类,这样所有使用JDK的人,用到的String类都是同一个,如果String允许被继承,每个人都可以对String进行扩展,每个人使用的String都不是同一个版本,两个不同的人使用相同的方法,表现出不同的结果,这就导致代码没办法进行开发了
继承和方法覆写在带来灵活性的同时,也会带来很多子类行为不一致的问题
2.创建字符串的四种方式
方式一:直接赋值(常用)
String str = " hello word "
方式二:通过构造方法产生对象
String str1 = new String(" hello word ");
方式三:通过字符数组产生对象
char[] data = new char[]{‘a’ , ‘b’ ,‘c’};
方式四:通过String的静态方法valueOf(任意数据类型) = >转为字符串(常用)
String str2 = String.valueOf(10);
3.字符串的字面量
字面量:直接写出来的数值叫做字面量
10 – > int字面量
10.1 --> double字面量
true --> boolean字面量
" abc " – > String字面量
字符串的字面量其实就是一个字符串对象
String str = “hello word”;
String str2 = str;
此时这既是一个字符串的字面量,也是字符串的对象,为了方便理解,画个图,此时是为了方便理解我们暂时先认为它储存在堆上,其实实在方法区中存放
此时让str2 = “Hello”;此时对str的输出并没有影响,因为被" "括起来的Hello也是一个字符串对象,说明此时在堆上新开辟了一块空间,而此时str2保存的就是新对象的地址空间,对str没有影响
4.字符串比较相等
所有的引用数据类型在比较是否相等时,使用equals方法比较,JDK的常用类,都已经覆写了equals方法,直接使用即可
引用数据类型使用 == 比较的是地址
下图是两个引用指向了同一块地址空间,和字符串的常量池有关
下图产生了两个对象,两块地址空间,使用==返回的就是false
equals的比较大小是区分大小写的比较
equalsIgnoreCase方法是不区分大小写的比较
二、字符串的常量池
1.什么是字符串常量池
当使用直接赋值法产生字符串对象的时候,JVM会维护一个字符串的常量池,若该对象在堆中还不存,就产生一个字符串对象加入到字符串常量池中;当继续使用直接赋值法产生字符串对象的时候,JVM发现该引用指向的内容在常量池中已经存在了,此时就不再新建字符串对象,而是直接复用已有的对象,这也是为什么上图的三个引用指向的是同一块地址
当第一次产生对象的时候,常量池中还什么都没有,就在常量池中产生一个字符串对象存入,当第二第三次产生对象时,JVM发现常量池中已经存在相同的内容,就不再产生新的对象,直接指向和str1相同的地址空间
程序都是从右向左执行的,此时第一行代码的右边就是一个字符串常量,也是一个字符串对象,所以先在常量池中开辟一块空间,然后新建一个字符串对象存入,程序再往左执行,遇到new关键字,此时新建一个对象存入堆中,然后str1 指向堆中的对象,在指向第二行第三行代码时,发现常量池中已经存在该对象,不再新建,遇到new关键字就新建对象,
内存图如下:
2.手工入池方法
String类提供的intern方法,这是一个本地方法:
调用intern方法会将当前字符串引用指向的对象保存到字符串常量池中,有两种情况:
1.若当前常量池中已经存在了该对象,则不再产生新的对象,返回常量池中的String对象
2.若当前常量池中不存在该对象,则将该对象入池,返回入池后的地址。
看一下下面这几行代码的输出:
因为intern方法是有返回值的,此时str1只是调用了intern方法,并没有接收返回值,所以str1还是指向堆中的对象,str2指向常量池中的对象,所以返回false;
只要接收一下调用intern方法的返回值,就会返回true;
此时就将str1指向的对象手动入池了,池中已有该对象,直接让str1指向该对象
再看看下面这几行代码的输出:
手动入池时,池中还没有任何东西,直接移入常量池中
三、字符串的不可变性 1.为什么不可变
注意:所谓的字符串不可变,指的是字符串的内容不可变,而不是字符串的引用不能变
这里的不可变指的是" hello " , " world " , " helloworld " , " !!! " , 以及拼接后的"helloworld!!!"这些已经创建好的字符串对象,这些对象一旦声明后就无法修改其内容,但是引用是可以改变的,一会指向hello,一会指向helloworld,一会指向hello world!!!,这都是可以的
字符串就是就是一个字符数组—> char[],字符串其实在字符数组中保存。字符串的内容为什么不能改变?我们看看字符串的源码就知道了。
我们可以看到String内部的字符数组是被封装起来的,String类的外部无法访问到这个字符数组,更何谈改变字符串的内容
String str = " hello ";
2.如何修改字符串内容
1.在运行时通过反射破坏value数组的封装
2.更换使用StringBuilder或者StringBuffer类 - - 已经不是一个类型了
a.StringBuilder:线程不安全,性能较强
b.StringBuffer:线程安全,性能较差
除此之外两个类的用法完全相同
若需要频繁的进行字符串的拼接,使用StringBuilder类的append方法,这里只产生了一个对象,一会变成hello,一会变成hello world
3.StringBuilder类的具体使用
StringBuilder类和String是两个独立的类,StringBuilder类就是为了解决字符串的拼接问题产生的
StringBuilder类和String类的相互转换:
1.StringBuilder变为String类调用toString方法即可
2.String类转变为StringBuilder类,使用StringBuilder的构造方法或者append方法
其他常用方法:
a.字符串的反转操作,sb提供的reverse();
b.删除指定范围的数据,delete(int start,int end);删除从start开始,到end之前的所有内容,左闭右开区间
c.插入操作,insert(int start,各种数据类型):从start索引位置开始插入,插入的起始索引为start
来源:https://blog.csdn.net/weixin_57011679/article/details/124925656


猜你喜欢
- 01、多线程下扩容会死循环众所周知,HashMap 是通过拉链法来解决哈希冲突的,也就是当哈希冲突时,会将相同哈希值的键值对通过链表的形式存
- 一、网络爬虫的基本知识网络爬虫通过遍历互联网络,把网络中的相关网页全部抓取过来,这体现了爬的概念。爬虫如何遍历网络呢,互联网可以看做是一张大
- Windows服务在Visual Studio 以前的版本中叫NT服务,在VS.net启用了新的名称。用Visual C# 创建Window
- Springmvc调用存储过程,并返回存储过程返还的数据java后端很多时候都需要和数据库进行交互,并返回业务数据。一般情况下都会采用执行S
- InputStreamReader和OutputStreamWriter源码分析1. InputStreamReader 源码(基于jdk1
- 前面有文章曾经地介绍过MediaPlayer的基本用法,这里就更加深入地讲解MediaPlayer的在线播放功能。本文主要实现MediaPl
- 有httponly的cookie,在httpwebreqeust请求时,会获取不到,可以采用直接获取head中的set-cookie,再转换
- 基于这段时间折腾redis遇到了各种问题,想着整理一下。本文主要介绍基于Spring+Mybatis以注解的形式整合Redis。废话少说,进
- 介绍: 本文章主要针对web项目中的两个问题进行详细解析介绍:1- 页面跳转404,即controller转发无法跳转页面问题;2- 静态资
- 其实没什么技术含量,因为老是想不起来,所以在此文做下记录。通常我们的应用系统中都会有很多短信的发送,或者是信息邮件等的推送,而这些信息却有着
- 最近项目在做新闻爬虫,想实现这个功能:爬虫某个页面失败后,把这个页面的 url 发到邮箱。最终实现的效果图如下,后期可以加上过滤标签、失败状
- 一、需求分析:1、输入一个数组-----------------------------------------》程序要接收一组输入的数组,
- 本文实例为大家分享了java实现查找替换功能的具体代码,供大家参考,具体内容如下查找if(searchTxt.getText().equal
- Android 界面刷新 Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,
- 一、项目简述功能: 前后用户的登录注册,婚纱照片分类,查看,摄影师预 订,后台订单管理,图片管理等等。二、项目运行环境配置: Jdk1.8
- Android本地存储SharedPreferences详解存储位置SharedPreferences数据保存在: /data /data/
- 在上一篇文章中,我为大家介绍了《5种创建文件并写入文件数据的方法》,本节我们为大家来介绍6种从文件中读取数据的方法.另外为了方便大家理解,我
- 一直以为这个方法是java8的,今天才知道是是1.7的时候,然后翻了一下源码。这片文章中会总结一下与a.equals(b)的区别,然后对源码
- 在我们将Winform自带的边框隐藏之后,我们需要自己编写窗口的移动。思路就是1.获得点击左键时当前鼠标的坐标2.获得移动后鼠标的坐标3.窗
- 一、C#方法中参数类型有4种参数类型,有时候很难记住它们的不同特征,下图对它们做一个总结,使之更容易比较和对照。二、C#方法中的参数1、值参