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.基础数据类型:比较的是他们的值是否 ...
随机推荐
- Vue的Router路由传参
一.文件结构 二.vue.js 打开此链接 https://cdn.bootcss.com/vue/2.6.10/vue.js 复制粘贴页面的所有内容 三.vue-router.js 打开此链接 h ...
- Ajax与PHP通信
以下是HTML的Js代码 $data = { va:$('#num').text() }; $.ajax({ type: 'POST', url: "A.php", data: $ ...
- vue-上传文件
<label for="exampleInputFile">头像</label> <img :src=" imgsrc != '' ? im ...
- springboot2.x整合JPA
项目结构 pom <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www. ...
- vue 弹窗时 监听手机返回键关闭弹窗(页面不跳转)
[注]: popstate 事件 a.当活动历史记录条目更改时,将触发popstate事件. b.如果被激活的历史记录条目是通过对history.pushState()的调用创建的,或者受到对his ...
- ReentrantReadWriteLock 可重入的读写锁
可重入:就是同一个线程可以重复加锁,可以对同一个锁加多次,每次释放的时候会释放一次锁,直到该线程加锁次数为0,这个线程才释放锁. 读写锁: 也就是读锁可以共享,多个线程可以同时拥有读锁,但是写锁却只能 ...
- 2018-8-10-win10-uwp-进度条-WaveProgressControl
title author date CreateTime categories win10 uwp 进度条 WaveProgressControl lindexi 2018-08-10 19:16:5 ...
- elasticsearch基础知识杂记
日常工作中用到的ES相关基础知识和总结.不足之处请指正,会持续更新. 1.集群的健康状况为 yellow 则表示全部主分片都正常运行(集群可以正常服务所有请求),但是 副本 分片没有全部处在正常状态. ...
- vue实现拖拽组件
可以拖拽,靠边停靠,效果图如下 代码如下: 注意:代码中使用的图片未上传 DragAndDrop组件: <template> <div class="drag" ...
- JVM内存结构探秘及编码实战
了解JVM内存结构的目的 在Java的开发过程中,因为有JVM自动内存管理机制,不再需要像在C.C++开发那样手动释放对象的内存空间,不容易出现内存泄漏和内存溢出的问题.但是,正是由于把内存管理的权利 ...