Java String类相关知识梳理(含字符串常量池(String Pool)知识)
目录
1. String类是什么
1.1 定义
1.2 类结构
1.3 所在的包
2. String类的底层数据结构
3. 关于 intern() 方法(重点)
3.1 作用
3.2 字符串常量池(String Pool)
4. String类所用的连接符
5. String类的主要作用(简)
正文
1. String类是什么
1.1 定义
String类表示字符串。Java程序中的所有字符串都是这个String的实例,比如"abc"。字符串为常数,它们的值在创建之后不能更改。因为字符串对象是不可变的,避免了现线程安全问题的出现,所以可以共享它们。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
问:“字符串为常数,它们的值在创建之后不能更改”——①这句话的具体表现(从String的使用角度出发)?②为什么要一经创建就不可更改?③怎么做到一经创建就不可更改的?
答:
①通过调用String的方法我们可以发现,String并未真正提供“字符串的修改”方法,诸如replace这类的字符串替换方法,也只是创建一个新的字符串来替换,而非在原字符串上进行替换;
②这个问题从字符串的使用场景来解释比较好理解:从用户使用时的安全性考虑(线程安全),八种基本数据类型的“复制”是再新创建一份相同的数据,而String其实也相当于是一种基本的数据类型,只是它有引用,比较复杂一些,所以字符串要一经创建就不能更改。
③封装:虽然String的底层数据结构是char数组(数组的内容是可以更改的),但是,String将该字段声明为private,且并不对外暴露修改数组内容的方法。
1.2 类结构
public final class String implements java.io.Serializable, Comparable<String>, CharSequence{……}
① final:String类不能被继承;
② Serializable:可序列化;
③ Comparable<String>:用于字符串之间的比较;
1.3 所在的包:java.lang
java.lang包是java语言的核心,它提供了java中的基础类。包括基本Object类、Class类、String类、基本类型的包装类、基本的数学类等等最基本的类。
2. String类的底层数据结构
private final char value[];//不可变的字符数组
问1. 如果说String的底层数据结构是“不可变的char数组”,那不应该是声明为“ private final char[] value;”吗?
答:这也是数组的一种声明方式,只是比较少见、少用,或许因为历史原因所以String保留使用着这种不常用的数组声明方式。
问2. 不可变的字符数组的声明只能保证String对象的引用不可变,而用了char数组来作为存储结构,只能保证字符串一经声明其长度不可变,但是数组中存储的内容时可以改变的,从何保证字符串一经声明就不能再变呢?
答:见 1.1的第③点;
3. 关于 intern() 方法(重点)
3.1 作用:该方法用于返回字符串对象的规范表示形式。
public native String intern();// native方法,看不到具体实现。
当调用intern方法时:
①如果字符串常量池中已经包含了一个由equals(object)方法确定的String对象的字符串,则返回池中的字符串。
②否则,将这个 String对象添加到池中(这是JDK1.8中intern()方法的注释给出的说明,但通过下面的测试,我认为是“将这个String对象的字符串内容添加到池中”会更好理解),并返回对这个String对象的引用。
@Test
public void test() { // 池中没有相应的字符串内容:
String s1 = new String("hello");// 在堆中生成"hello"字符串对象
String s2 = s1.intern();// 执行“s1.intern()”时,String Pool中没有"hello",会直接先将s1对象的字符串内容“hello”复制到池中
System.out.println(s1 == s2); // false,s1指向堆中的对象,s2指向字符串常量池中的字符常量。
System.out.println(s1.intern()); // hello // 池中有:
String s3 = "world"; // 直接在String Pool中生成"world"字符串
String s4 = s3.intern(); // 从池中拿"world"字符串返回给s4
System.out.println(s3 == s4); // true
}
3.2 字符串常量池(String Pool)
字符串常量池最初是空的,由类 String私下维护。
(1)在哪儿
在JDK6及之前版本:字符串常量池是放在永久代中;
在JDK7版本中:字符串常量池被移到了堆中。
(2)数据结构
在HotSpot VM中字符串常量池是通过一个StringTable类(一个Hash表,并非java实现类,所以知道即可)实现的;这个StringTable在每个HotSpot VM的实例中只有一份,被所有的类共享;
(3)存放的内容
在JDK6及之前版本:String Pool里放的都是字符串常量;
在JDK7.0中:由于String.intern()发生了改变,因此String Pool中也可以存放放于堆内的字符串对象的引用。
(4)特性:常量池中不存在两个相同的对象
(5)字符串常量池存在的意义(为什么要有它?):避免字符串常量的重复创建,节省内存空间。
(6)什么情况下生成的字符串才会被放到String Pool中?
① 字面量:代码中直接使用双引号引着的字符串都会被存储到字符串常量池中,如:String abc = "abc";;
② 调用String的 intern()方法,如果字符串内容是字符串常量池中没有的,那么会先复制一份内容到字符串常量池中;
4. String类所用的连接符
Java语言为“+”连接符以及将对象转换为字符串提供了特殊的支持:
字符串对象可以使用“+”连接其他对象。其实字符串连接是通过StringBuilder(或 StringBuffer)及其 append()方法 实现的。
字符串转换是通过 toString()方法实现的,该方法由Object定义,并由Java中的所有类继承。
5. String类的主要作用(简)
  ①检查序列的单个字符、
  ②比较字符串、
  ③搜索字符串、
  ④提取子字符串
  ⑤创建一个字符串的副本的方法,
  ⑥大小写转换;
  ⑦更多;
Java String类相关知识梳理(含字符串常量池(String Pool)知识)的更多相关文章
- [JAVA]字符串常量池String pool
		
字符串常量池(String Pool)保存着所有字符串字面量(literal strings),这些字面量在编译时期就确定.不仅如此,还可以使用 String 的 intern() 方法在运行过程中将 ...
 - 结合字符串常量池/String.intern()/String Table来谈一下你对java中String的理解
		
1.字符串常量池 每创建一个字符串常量,JVM会首先检查字符串常量池,如果字符串已经在常量池中存在,那么就返回常量池中的实例引用.如果字符串不在池中,就会实例化一个字符串放到字符串池中.常量池提高了J ...
 - 常量池之字符串常量池String.intern()
		
运行时常量池是方法区(PermGen)的一部分. 需要提前了解: 1. JVM内存模型. 2. JAVA对象在JVM中内存分配 常量池的好处 常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现 ...
 - String类的intern()方法,随常量池发生的变化
		
JVM的知识这里总结的很详细:https://github.com/doocs/jvm/blob/master/README.md,因此在本博客也不会再对其中的东西重复总结了. intern的作用 简 ...
 - java值和地址值传递、字符串常量池的理解
		
#java值和地址值传递的理解: - 基本数据类型和基本数据类型的封装类都是:值传递 * 形式参数的改变不会影响实际参数的改变(相当于将值复制一份传递给形参,自身没做任何改变) - 引用数据 ...
 - Java中,那些关于String和字符串常量池你不得不知道的东西
		
老套的笔试题 在一些老套的笔试题中,会要你判断s1==s2为false还是true,s1.equals(s2)为false还是true. String s1 = new String("xy ...
 - Java中String字符串常量池总结
		
最近到广州某建站互联网公司面试,当时面试官问假设有两个字符串String a="abc",String b = "abc";问输出a==b是true还是fals ...
 - Java中的常量池(字符串常量池、class常量池和运行时常量池)
		
转载. https://blog.csdn.net/zm13007310400/article/details/77534349 简介: 这几天在看Java虚拟机方面的知识时,看到了有几种不同常量池的 ...
 - Java字符串常量池及字符串判等解析
		
一.理解"=="的含义 "=="常用于两个对象的判等操作,在Java中,"=="主要有以下两种用法: 1.基础数据类型:比较的是他们的值是否 ...
 
随机推荐
- hdu 1596 find the safest road (变形SP && dij+heap)
			
Problem - 1596 变形最短路问题,给出邻接矩阵,要求求出给定点对间安全率最大值. 这题可以用dijkstra+heap来做.对于每一个查询,做一次dij即可. 代码如下: #include ...
 - hdu 3374 String Problem (字符串最小最大表示 + KMP求循环节)
			
Problem - 3374 KMP求循环节. http://www.cnblogs.com/wuyiqi/archive/2012/01/06/2314078.html 循环节推导的证明相当 ...
 - OpenCV 安装与调试
			
Visual Studio 是微软提供的面向任何开发者的同类最佳工具. OpenCV(开源计算机视觉库)是一个开源的计算机视觉和机器学习软件库. 目前最新版本:Visual Studio 2019.O ...
 - oracle中 =: 和 := 分别是什么意思
			
oracle中 =: 和 := 分别是什么意思 =:应该相当于 a = :b 表明b是个绑定变量,需要执行时进行变量绑定:= 相当于一般编程语言中的 赋值 a := 1 即将 数字1赋值给变量 a
 - 洛谷P5020 货币系统 题解 模拟
			
题目链接:https://www.luogu.org/problem/P5020 这道题目是一道模拟题,但是又有一点多重背包的思想在里面. 首先我们定义一个 vis[i] 来表示和为 i 的情况在之前 ...
 - iptables典型NAT上网
			
一般做为NAT的计算机同时也是局域网的网关,假定该机有两块网卡eth0.eth1,eth0连接外网,IP为202.96.134.134:eth1连接局域网,IP为192.168.62.10 1. 先在 ...
 - js对数组的元素分割
			
文章地址 https://www.cnblogs.com/sandraryan/ 不用方法(模拟方法) <script> var arr = ["hi",2,3,tru ...
 - Canvas文本设置
			
本文的应用对Canvas文本设置相关属性进行了汇总,具体使用说明请参考下面代码: <!DOCTYPE html> <html lang="zh"> < ...
 - Python涉及的各个领域以及技术应用
			
WEB开发 完全主义者高效率框架Django 异步高并发Tornado框架 短小精悍Flask,Bottle框架 网络编程 高并发Twisted网络框架 Python3引入的asyncio异步编程 爬 ...
 - 【矩阵乘法优化dp】[Codeforces 621E] Wet Shark and Blocks
			
http://codeforces.com/problemset/problem/621/E E. Wet Shark and Blocks time limit per test 2 seconds ...