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). 这是最快的存储区,因为它位于不同于其他存储区的地方——处理器内部.但是寄存器的数量极其有限,所以寄存器由编译器根据 ...
随机推荐
- CF1313C2 Skyscrapers (hard version)
思路: 使用单调栈. 实现: 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 con ...
- 神奇C语言的字串处理库函数
头文件:#incldue<string.h> 定义:strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串.如果是,则该函数返回str2在str1中首次出现的地 ...
- Educational DP Contest F - LCS (LCS输出路径)
题意:有两个字符串,求他们的最长公共子序列并输出. 题解:首先跑个LCS记录一下dp数组,然后根据dp数组来反着还原路径,只有当两个位置的字符相同时才输出. 代码: char s[N],t[N]; i ...
- Linux系统编程【3.1】——编写ls命令
ls命令简介 老规矩,直接在终端输入:man ls (有关于man命令的简介可以参考笔者前期博客:Linux系统编程[1]--编写more命令) 可以看到,ls命令的作用是显示目录中的文件名,它带有可 ...
- codeforces 14D(搜索+求树的直径模板)
D. Two Paths time limit per test 2 seconds memory limit per test 64 megabytes input standard input o ...
- Fullscreen API All In One
Fullscreen API All In One 全屏显示 https://developer.mozilla.org/en-US/docs/Web/API/Fullscreen_API https ...
- ThoughtWorks Homework
ThoughtWorks Homework Homework 考察知识点 项目搭建 技术选型 测试 编码风格 代码质量 设计模式 数据结构 算法 架构 开源协作 CI/CD DevOps Linux ...
- HTML5 in depth
HTML5 in depth Content Models Web Storage web storage 存储用户信息, 替代 cookies LocalStorage SessionStorage ...
- Web Components & HTML template & HTML slot
Web Components & HTML template & HTML slot https://github.com/xgqfrms/es-next/issues/2 live ...
- rem & 16px & 62.5%
rem & 16px & 62.5% 浏览器的默认字体大小都是16px 兼容性:IE9+,Firefox.Chrome.Safari.Opera 的主流版本都支持了rem 对不支持的浏 ...