转载。 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. 使用google autoservice 自动生成java spi 描述文件

    spi 是一种服务发现的标准,对于开发中我们通常需要编写 META-INF/services 文件夹中定义的类. google auto 中的autoservice 可以帮助我们生成对应的配置,很方便 ...

  2. 使用s3-sftp-proxy 暴露minio s3 数据为sftp 访问

    尽管s3 很不错,但是ftp 也有自己存在的价值,以下是一个简单的通过s3-sftp-proxy 暴露minio s3 数据为ftp 的访问方式 环境准备 docker-compose 文件 vers ...

  3. A|G\C003

    AGC003 A Wanna go back home = = https://agc003.contest.atcoder.jp/submissions/7910739 B Simplified m ...

  4. 【CF241E】Flights

    [CF241E]Flights 题面 洛谷 题解 对于原来的图,如果一条边不出现在\(1\)到\(n\)的路径上面,直接\(ban\)掉即可. 那么考虑一条边\(u\rightarrow v\),一定 ...

  5. 04-树6 Complete Binary Search Tree (30 分)

    A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...

  6. ImportError: cannot import name 'BaseDataset' from 'src.dataset'

    因为我进行了相互调用,我在父类中调用了子类. from src.dataset import BaseDataset class PSINSDataset(BaseDataset): from src ...

  7. 分布式系统之CAP原理

    参考链接:http://blog.csdn.net/wireless_com/article/details/79153643 CAP是什么? CAP理论,被戏称为[帽子理论].CAP理论由Eric ...

  8. Jdk8 DNS解析

    注:JDK7和JDK8关于DNS解析的实现有差异,该问题在JDK7下可能不存在: Java中的DNS解析一般是通过调用下面的方法: public static InetAddress getByNam ...

  9. Django实现自动发布(3发布-安装)

    相对于服务的升级.回退,新部署一个服务要复杂一些,要满足以下要求: 已经运行了服务实例的主机不能重复部署 进程启动需要的配置文件要先同步到主机上 之前的升级.回退都是指进程的操作,不涉及配置文件的变更 ...

  10. error: dereferencing pointer to incomplete type

    /******************************************************************************* * error: dereferenc ...