目录

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)知识)的更多相关文章

  1. [JAVA]字符串常量池String pool

    字符串常量池(String Pool)保存着所有字符串字面量(literal strings),这些字面量在编译时期就确定.不仅如此,还可以使用 String 的 intern() 方法在运行过程中将 ...

  2. 结合字符串常量池/String.intern()/String Table来谈一下你对java中String的理解

    1.字符串常量池 每创建一个字符串常量,JVM会首先检查字符串常量池,如果字符串已经在常量池中存在,那么就返回常量池中的实例引用.如果字符串不在池中,就会实例化一个字符串放到字符串池中.常量池提高了J ...

  3. 常量池之字符串常量池String.intern()

    运行时常量池是方法区(PermGen)的一部分. 需要提前了解: 1. JVM内存模型. 2. JAVA对象在JVM中内存分配 常量池的好处 常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现 ...

  4. String类的intern()方法,随常量池发生的变化

    JVM的知识这里总结的很详细:https://github.com/doocs/jvm/blob/master/README.md,因此在本博客也不会再对其中的东西重复总结了. intern的作用 简 ...

  5. java值和地址值传递、字符串常量池的理解

    #java值和地址值传递的理解: - 基本数据类型和基本数据类型的封装类都是:值传递    * 形式参数的改变不会影响实际参数的改变(相当于将值复制一份传递给形参,自身没做任何改变)   - 引用数据 ...

  6. Java中,那些关于String和字符串常量池你不得不知道的东西

    老套的笔试题 在一些老套的笔试题中,会要你判断s1==s2为false还是true,s1.equals(s2)为false还是true. String s1 = new String("xy ...

  7. Java中String字符串常量池总结

    最近到广州某建站互联网公司面试,当时面试官问假设有两个字符串String a="abc",String b = "abc";问输出a==b是true还是fals ...

  8. Java中的常量池(字符串常量池、class常量池和运行时常量池)

    转载. https://blog.csdn.net/zm13007310400/article/details/77534349 简介: 这几天在看Java虚拟机方面的知识时,看到了有几种不同常量池的 ...

  9. Java字符串常量池及字符串判等解析

    一.理解"=="的含义 "=="常用于两个对象的判等操作,在Java中,"=="主要有以下两种用法: 1.基础数据类型:比较的是他们的值是否 ...

随机推荐

  1. jq动画和停止动画

    使用jq 实现动画循环效果 <!DOCTYPE html> <html lang="en"> <head> <meta charset=& ...

  2. 洛谷P3150 pb的游戏(1)题解 博弈论入门

    题目链接:https://www.luogu.org/problem/P3150 这道题目是博弈论的入门题. 我们以 必胜态 和 必败态 来讲解这个问题. 首先,下面的图片演示了前8个数的必胜态和必败 ...

  3. js实现点击隐藏图片

    方法一: 把图片的display设为none,触发点击事件时,display变为block <style> img { width: 400px;height: 300px; displa ...

  4. 21个项目玩转深度学习:基于TensorFlow的实践详解02—CIFAR10图像识别

    cifar10数据集 CIFAR-10 是由 Hinton 的学生 Alex Krizhevsky 和 Ilya Sutskever 整理的一个用于识别普适物体的小型数据集.一共包含 10 个类别的 ...

  5. P1003 电影票价

    题目描述 已知一位小朋友的电影票价是10元,请问 \(n\) 位小朋友的总票价是多少? 输入格式 输入一个整数 \(n(1 \le n \le 1000)\) , 用于表示小朋友的数量. 输出格式 输 ...

  6. 2018-8-10-win10-uwp-x_Bind-无法获得资源

    title author date CreateTime categories win10 uwp x:Bind 无法获得资源 lindexi 2018-08-10 19:17:19 +0800 20 ...

  7. vue中处理时间格式化的问题

    vue main.js中修改Date原型链,插入(百度) Date.prototype.format = function(fmt) { var o = { "M+" : this ...

  8. Linux 内核存取配置空间

    在驱动已探测到设备后, 它常常需要读或写 3 个地址空间: 内存, 端口, 和配置. 特别 地, 存取配置空间对驱动是至关重要的, 因为这是唯一的找到设备被映射到内存和 I/O 空间的位置的方法. 因 ...

  9. 【51.64%】【POJ 1330】Nearest Common Ancestors

    Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 26416 Accepted: 13641 Description A roote ...

  10. Java基础系列8——IO流超详细总结

    该系列博文会告诉你如何从入门到进阶,一步步地学习Java基础知识,并上手进行实战,接着了解每个Java知识点背后的实现原理,更完整地了解整个Java技术体系,形成自己的知识框架. 在初学Java时,I ...