Java进阶——Java中的字符串常量池
字符串常量池
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个
- 在常量池中查找是否有”abc”对象,有则返回对应的引用实例,没有则创建对应的实例对象(1个)
- 在堆中 new 一个 String(“abc”) 对象(1个)
- 将对象地址赋值给str,创建一个引用
2、String str = new String(“A”+”B”)创建多少个对象?4个
- 在常量池中查找,字符串”A”,”B”,”AB”(3个)
- 在堆中 new 一个 String(“AB”) 对象(1个)
- 将对象地址赋值给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中的字符串常量池的更多相关文章
- Java中String字符串常量池总结
最近到广州某建站互联网公司面试,当时面试官问假设有两个字符串String a="abc",String b = "abc";问输出a==b是true还是fals ...
- Java中String字符串常量池
首先看一个例子,通过这个例子更能快速理解String常量池 public static void main(String[] args) { String a = "ab"; St ...
- 转载:Java中的字符串常量池详细介绍
引用自:http://blog.csdn.net/langhong8/article/details/50938041 这篇文章主要介绍了Java中的字符串常量池详细介绍,JVM为了减少字符串对象的重 ...
- Java中的字符串常量池,栈和堆的概念
问题:String str = new String(“abc”),“abc”在内存中是怎么分配的? 答案是:堆内存.(Tips:jdk1.8 已经将字符串常量池放在堆内存区) 题目考查的为Ja ...
- Java中的字符串常量池
ava中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid";,另一种就是使用new这种标准的构造对象的方法,如String str = new ...
- Java中的字符串常量池和JVM运行时数据区的相关概念
什么是字符串常量池 JVM为了减少字符串对象的重复创建,其维护了一个特殊的内存,这段内存被成为字符串常量池或者字符串字面量池 工作原理 当代码中出现字面量形式创建字符串对象时,JVM首先会对这个字面量 ...
- Java中的字符串常量池?
参考:http://droidyue.com/blog/2014/12/21/string-literal-pool-in-java/index.html
- Java字符串常量池是什么?为什么要有这种常量池?
简单介绍 Java中的字符串常量池(String Pool)是存储在Java堆内存中的字符串池.我们知道String是java中比较特殊的类,我们可以使用new运算符创建String对象,也可以用双引 ...
- Java String类相关知识梳理(含字符串常量池(String Pool)知识)
目录 1. String类是什么 1.1 定义 1.2 类结构 1.3 所在的包 2. String类的底层数据结构 3. 关于 intern() 方法(重点) 3.1 作用 3.2 字符串常量池(S ...
随机推荐
- 使用google autoservice 自动生成java spi 描述文件
spi 是一种服务发现的标准,对于开发中我们通常需要编写 META-INF/services 文件夹中定义的类. google auto 中的autoservice 可以帮助我们生成对应的配置,很方便 ...
- 使用s3-sftp-proxy 暴露minio s3 数据为sftp 访问
尽管s3 很不错,但是ftp 也有自己存在的价值,以下是一个简单的通过s3-sftp-proxy 暴露minio s3 数据为ftp 的访问方式 环境准备 docker-compose 文件 vers ...
- A|G\C003
AGC003 A Wanna go back home = = https://agc003.contest.atcoder.jp/submissions/7910739 B Simplified m ...
- 【CF241E】Flights
[CF241E]Flights 题面 洛谷 题解 对于原来的图,如果一条边不出现在\(1\)到\(n\)的路径上面,直接\(ban\)掉即可. 那么考虑一条边\(u\rightarrow v\),一定 ...
- 04-树6 Complete Binary Search Tree (30 分)
A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...
- ImportError: cannot import name 'BaseDataset' from 'src.dataset'
因为我进行了相互调用,我在父类中调用了子类. from src.dataset import BaseDataset class PSINSDataset(BaseDataset): from src ...
- 分布式系统之CAP原理
参考链接:http://blog.csdn.net/wireless_com/article/details/79153643 CAP是什么? CAP理论,被戏称为[帽子理论].CAP理论由Eric ...
- Jdk8 DNS解析
注:JDK7和JDK8关于DNS解析的实现有差异,该问题在JDK7下可能不存在: Java中的DNS解析一般是通过调用下面的方法: public static InetAddress getByNam ...
- Django实现自动发布(3发布-安装)
相对于服务的升级.回退,新部署一个服务要复杂一些,要满足以下要求: 已经运行了服务实例的主机不能重复部署 进程启动需要的配置文件要先同步到主机上 之前的升级.回退都是指进程的操作,不涉及配置文件的变更 ...
- error: dereferencing pointer to incomplete type
/******************************************************************************* * error: dereferenc ...