new String("abc"),到底在不在常量池中存储"abc"?
String str = new String("Hello World");
问之:这行代码到底有没有在字符串常量池中创建“Hello World”字符串呢?
答曰:有。
问之:为什么?
答曰:先看String类的构造函数。
public String(String original){
//body
}
在这个过程中,“Hello World"作为形参传递给original,这个过程相当于 String original = “Hello World",因此,在常量池中创建字符串“Hello World"。
之后,我们都知道,new的对象都存在在堆中,因此,new String(“Hello World")在堆中创建了对象,并将其赋值给str,即 String str = 。
这么一来,在字符串常量池中存在字符串“Hello World",在堆中存在对象“Hello World"。
然鹅, str == s 并不为true。因为字符串常量池在方法区中(在JDK 1.8之后就放在堆中开辟的一块内存中了),new的对象在堆中,方法区与堆是不同的内存空间。
因此, str == s为false。
String str = new String("Hello World");
String s = "Hello World";
问曰:不是有个intern()函数吗?
答之:Of course。
问曰:那下面的代码str == s 返回true了吗?
String str = new String("Hello World");
str.intern();
String s = "Hello World";
答之:Of course not。因为前面已经说过了,String str = new String(“Hello World");语句已经在常量池中创建了“Hello World",那么str.intern();就不起作用啦。所以,等效于不加这一句。
问曰:那str.intern();就是鸡肋了吗?
答之:存在即合理。请往下看
String str = new String("Hello") + new String(" World");
str.intern(); // 注意这一行的顺序,要在下一行之前。否则,也不起作用啦。
String s = "Hello World";
好了,这次终于返回true了(在JDK1.7及以后),因为,常量池中虽然存在"Hello"和" World",但是不存在"Hello World",这个只有在堆中存在。
JDK 1.7以后,在堆中存在而不在常量池中存在的字符串,在常量池中存放其引用,因此str和指向同一块内存。
JDK 1.7以前,由于常量池不在堆中,那么存放的还是字符串本身,因此仍返回false。
【大写加粗】以上是参考一些资料和自己的思考,欢迎批评指正。
new String("abc"),到底在不在常量池中存储"abc"?的更多相关文章
- java常量池中基本数据类型包装类的小陷阱
想必大部分学过java的人都应该做过这种题目: public class Test { public static void main(String[] args) { //第一个字符串 String ...
- JVM体系结构之七:持久代、元空间(Metaspace) 常量池==了解String类的intern()方法、常量池介绍、常量池从Perm-->Heap
一.intern()定义及使用 相信绝大多数的人不会去用String类的intern方法,打开String类的源码发现这是一个本地方法,定义如下: public native String inter ...
- 运行时常量池中的符号引用/String.intern() /ldc指令
运行时常量池,之前放在方法区(永久代)中,1.8之后被转移到元空间,放到了native memory中. 具体的数据结构是:(看对象的内存布局,句柄访问还是对象头中保存指向类的元数据的指针,这里以对象 ...
- java---堆、栈、常量池的存储数据
说到Java中堆.栈和常量池,首先还是看看他们各自存放的数据类型吧! 栈: Java的JVM的内存可分为3个区:堆(heap).栈(stack)和方法区(method)也叫静态存储区. 堆区:(存放所 ...
- Java堆、栈和常量池以及相关String的详细讲解(经典中的经典) (转)
原文链接 : http://www.cnblogs.com/xiohao/p/4296088.html 一:在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register). 这是最快的 ...
- Java堆、栈和常量池以及相关String的详细讲解
一:在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register). 这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部.但是寄存器的数量极其有限,所以寄存器由编译器根据 ...
- Java堆、栈和常量池以及相关String详解
一:在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register). 这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部.但是寄存器的数量极其有限,所以寄存器由编译器根据 ...
- Java堆、栈和常量池以及相关String的详细讲解(转)
一:在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register). 这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部.但是寄存器的数量极其有限,所以寄存器由编译器根据 ...
- Java堆/栈/常量池以及String的详细详解(转)------经典易懂系统
一:在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register). 这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部.但是寄存器的数量极其有限,所以寄存器由编译器根据 ...
随机推荐
- Codeforces Round #343 (Div. 2) E. Famil Door and Roads (树形dp,lca)
Famil Door's City map looks like a tree (undirected connected acyclic graph) so other people call it ...
- Ancient Printer HDU - 3460 贪心+字典树
The contest is beginning! While preparing the contest, iSea wanted to print the teams' names separat ...
- 8.PowerShell DSC之Push
前言 LCM的默认mode就是push,所以对于push模式,我们直接就三步走 以下是示例: 1.编写配置 Authoring Configuration WebsiteTest { # Import ...
- MySQL 字符集及校验规则
字符集 Mysql 的字符集有4个级别的默认设置:服务器级,数据库级,表级和字段级,客户端交互时,也可以指定字符集 # 字符集:是一个系统支持的所有抽象字符的集合.字符是各种文字和符号的总称,包括各国 ...
- wordpress 插件安装 Too Many Requests
解决办法是在插件界面不直接点击安装/更新,右键新标签页打开链接,会有下载地址. 下载后上传插件即可.
- C++中关于输入cin的一些总结
(1)cin 在理解cin功能时,不得不提标准输入缓冲区.当我们从键盘输入字符串的时候需要敲一下回车键才能够将这个字符串送入到缓冲区中,那么敲入的这个回车键(\r)会被转换为一个换行符\n,这个换行符 ...
- mybatis(三)配置mapper.xml 的基本操作
参考:https://www.cnblogs.com/wuzhenzhao/p/11101555.html XML 映射文件 本文参考mybatis中文官网进行学习总结:http://www.myba ...
- 011.NET5_MVC解读Razor混编
MVC开发 1. 什么是MVC? V-视图,呈现给用户看到的内容---表现层 C-控制器,控制业务逻辑计算,可定义多种返回类型.可以是视图模型.JSON.字符串等等 M-视图模型,用于视图和控制之间传 ...
- keras自定义网络层
在深度学习领域,Keras是一个高度封装的库并被广泛应用,可以通过调用其内置网络模块(各种网络层)实现针对性的模型结构:当所需要的网络层功能不被包含时,则需要通过自定义网络层或模型实现. 如何在ker ...
- webpack 5 new features All In One
webpack 5 new features All In One Webpack 5 release (2020-10-10) https://webpack.js.org/blog/2020-10 ...