目录

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. Vue的Router路由传参

    一.文件结构 二.vue.js 打开此链接 https://cdn.bootcss.com/vue/2.6.10/vue.js 复制粘贴页面的所有内容 三.vue-router.js 打开此链接  h ...

  2. Ajax与PHP通信

    以下是HTML的Js代码 $data = { va:$('#num').text() }; $.ajax({ type: 'POST', url: "A.php", data: $ ...

  3. vue-上传文件

    <label for="exampleInputFile">头像</label> <img :src=" imgsrc != '' ? im ...

  4. springboot2.x整合JPA

    项目结构 pom <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www. ...

  5. vue 弹窗时 监听手机返回键关闭弹窗(页面不跳转)

    [注]:  popstate 事件 a.当活动历史记录条目更改时,将触发popstate事件. b.如果被激活的历史记录条目是通过对history.pushState()的调用创建的,或者受到对his ...

  6. ReentrantReadWriteLock 可重入的读写锁

    可重入:就是同一个线程可以重复加锁,可以对同一个锁加多次,每次释放的时候会释放一次锁,直到该线程加锁次数为0,这个线程才释放锁. 读写锁: 也就是读锁可以共享,多个线程可以同时拥有读锁,但是写锁却只能 ...

  7. 2018-8-10-win10-uwp-进度条-WaveProgressControl

    title author date CreateTime categories win10 uwp 进度条 WaveProgressControl lindexi 2018-08-10 19:16:5 ...

  8. elasticsearch基础知识杂记

    日常工作中用到的ES相关基础知识和总结.不足之处请指正,会持续更新. 1.集群的健康状况为 yellow 则表示全部主分片都正常运行(集群可以正常服务所有请求),但是 副本 分片没有全部处在正常状态. ...

  9. vue实现拖拽组件

    可以拖拽,靠边停靠,效果图如下 代码如下: 注意:代码中使用的图片未上传 DragAndDrop组件: <template> <div class="drag" ...

  10. JVM内存结构探秘及编码实战

    了解JVM内存结构的目的 在Java的开发过程中,因为有JVM自动内存管理机制,不再需要像在C.C++开发那样手动释放对象的内存空间,不容易出现内存泄漏和内存溢出的问题.但是,正是由于把内存管理的权利 ...