转载。 https://blog.csdn.net/qq_30379689/article/details/80518283

字符串常量池

JVM为了减少字符串对象的重复创建,其内部维护了一个特殊的内存,这段内存被成为字符串常量池(方法区中)。实际上还有整型常量池、浮点型常量池等等。字符串常量池存放的是对象的引用,而不是对象。Java中字符串对象创建有两种形式:字面量形式和创建对象形式

1、字面量形式

字面量的体现形式String str = "Hello",简单理解为去字符串常量池中拿对象的引用

当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量进行检查,如果字符串常量池中存在相同内容的字符串对象的引用,则将这个引用返回,否则新的字符串对象被创建,然后将这个引用放入字符串常量池,并返回该引用

2、创建对象形式

创建对象的体现形式String str = new String("Hello");,简单理解为直接在堆内存空间中创建新的对象

当代码中出现了new来构造字符串对象的时候,不管字符串常量池中有没有相同内容的对象的引用,首先它都会去创建这个字符串对象,这里字符串对象指的是String对象,String对象存放在堆当中。然后它会去字符串常量池寻找Hello这个字符串,其处理的结果同字面量形式。最终str引用指向String对象的引用

字符串对象创建

1、String str = new String(“abc”) 创建多少个对象?2个

  1. 在常量池中查找是否有”abc”对象,有则返回对应的引用实例,没有则创建对应的实例对象(1个)
  2. 在堆中 new 一个 String(“abc”) 对象(1个)
  3. 将对象地址赋值给str,创建一个引用

2、String str = new String(“A”+”B”)创建多少个对象?4个

  1. 在常量池中查找,字符串”A”,”B”,”AB”(3个)
  2. 在堆中 new 一个 String(“AB”) 对象(1个)
  3. 将对象地址赋值给str,创建一个引用

问题抛出

问:求解下面的输出语句的结果并解释原因

String s1 = "Hello";
String s2 = "Hello";
String s3 = "Hel" + "lo";
String s4 = "Hel" + new String("lo");
String s5 = new String("Hello");
String s6 = s5.intern();
String s7 = "H";
String s8 = "ello";
String s9 = s7 + s8; // == :比较两个对象是否为同一对象
System.out.println(s1 == s2); // true
System.out.println(s1 == s3); // true
System.out.println(s1 == s4); // false
System.out.println(s1 == s9); // false
System.out.println(s4 == s5); // false
System.out.println(s1 == s6); // true

问题分析

1、s1==s2

s1和s2在赋值时,均使用的字符串字面量。在编译期间,这种字面量会直接放入常量池中,从而实现复用。在载入运行时常量池后,s1和s2指向的是同一个内存地址

2、s1==s3

s3是动态拼接出来的字符串,但是所有参与拼接的部分都是已知的字面量。在编译期间,这种拼接会被优化,编译器直接帮你拼好,因此s3会被优化成String s3 = "Hello"

3、s1==s4

s4是动态拼接出来的字符串,但new String("lo")这部分不是已知字面量,是一个不可预料的部分。在编译期间,编译器不会优化,必须等到运行时才可以确定结果

4、s1==s9

s7和s8在赋值的时候使用的字符串字面量,但是拼接成s9的时候,s7和s8作为两个变量,都是不可预料的。编译器毕竟是编译器,不可能当解释器用,所以不做优化。等到运行时,s7和s8拼接成的新字符串,在堆中地址不确定,不可能与方法区常量池中的s1地址相同

5、s4==s5

s4和s5都创建出了字符串对象,两者都存在于堆中,但地址不相同

6、s1==s6

对于使用new创建的字符串对象,如果想将这个对象的引用加入到字符串常量池,可以使用intern方法。调用intern后,首先检查字符串常量池中是否有该对象的引用,如果存在,则将这个引用返回给变量,否则将引用加入并返回给变量。很显然,s1和s6都已经是字符串常量池中的一员,且值是相等的,所以引用的地址也相等

Java进阶——Java中的字符串常量池的更多相关文章

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

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

  2. Java中String字符串常量池

    首先看一个例子,通过这个例子更能快速理解String常量池 public static void main(String[] args) { String a = "ab"; St ...

  3. 转载:Java中的字符串常量池详细介绍

    引用自:http://blog.csdn.net/langhong8/article/details/50938041 这篇文章主要介绍了Java中的字符串常量池详细介绍,JVM为了减少字符串对象的重 ...

  4. Java中的字符串常量池,栈和堆的概念

    问题:String str = new String(“abc”),“abc”在内存中是怎么分配的?    答案是:堆内存.(Tips:jdk1.8 已经将字符串常量池放在堆内存区) 题目考查的为Ja ...

  5. Java中的字符串常量池

    ava中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid";,另一种就是使用new这种标准的构造对象的方法,如String str = new ...

  6. Java中的字符串常量池和JVM运行时数据区的相关概念

    什么是字符串常量池 JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池 工作原理 当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量 ...

  7. Java中的字符串常量池?

    参考:http://droidyue.com/blog/2014/12/21/string-literal-pool-in-java/index.html

  8. Java字符串常量池是什么?为什么要有这种常量池?

    简单介绍 Java中的字符串常量池(String Pool)是存储在Java堆内存中的字符串池.我们知道String是java中比较特殊的类,我们可以使用new运算符创建String对象,也可以用双引 ...

  9. Java String类相关知识梳理(含字符串常量池(String Pool)知识)

    目录 1. String类是什么 1.1 定义 1.2 类结构 1.3 所在的包 2. String类的底层数据结构 3. 关于 intern() 方法(重点) 3.1 作用 3.2 字符串常量池(S ...

随机推荐

  1. 【JVM】内存和SWAP问题

    一.现象 1.系统稳定运行,偶尔发生响应超时的情况.查看下游依赖服务和数据库状态都良好.超时完全是由于服务本身问题造成的.重启不能解决问题,一直会间隔性的发生超时 二.原因分析 第一种情况,系统内存够 ...

  2. Ubuntu下手动安装vscode

    Ubuntu下手动安装vscode1.下载vscodewget https://vscode.cdn.azure.cn/stable/553cfb2c2205db5f15f3ee8395bbd5cf0 ...

  3. nginx之系统参数优化

    系统参数优化 默认的Linux内核参数考虑的是最通用场景,不符合用于支持高并发访问的Web服务器的定义,根据业务特点来进行调整,当Nginx作为静态web内容服务器.反向代理或者提供压缩服务器的服务器 ...

  4. 云服务器搭建JDK+Tomcat+MySQL环境

    一.首先租赁一台云服务器(阿里云服务器或者腾讯云服务器) 其实可以在windows电脑上使用VMware workstation来安装虚拟机进行操作,毕竟云服务器低配也是很贵的.不过可以使用学生价去租 ...

  5. html上传文件限制、前端限制文件类型

    <input id="file" type="file" accept=".xls,.xlsx" style="width: ...

  6. C#控制台程序入口函数 Main(string[] args) 参数详解

    学习C#编程最常见的示例程序是在控制台应用程序中输出Hello World! using System; namespace DemoMainArgs { class Program { static ...

  7. docker安装 与 基本配置

    1.安装docker #yum remove docker \ docker-common \ container-selinux \ docker-selinux \ docker-engine \ ...

  8. leetcode:7. 整数反转

    题目描述: 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例: 输入: 123 输出: 321 输入: -123 输出: -321 输入: 120 输出: 21 注意:假 ...

  9. 引用fastclick.js或使用触屏监听 滑动屏幕报错:解决[Intervention] Unable to preventDefault inside passive event listener

    使用fastClick.js所产生的一些问题 开发h5活动页时想到移动端会有300ms的延迟,于是便打算用fastClick.js解决. 页面引入fastClick.js后,滑动H5页面的时候发现谷歌 ...

  10. Base64编码解码(js)

    开源的base64.js,使用很简单,浏览器引入该JS文件,然后Base64编码这样: Base64.encode('china is so nb'); // 编码 "Y2hpbmEgaXM ...