JDK1.7 及之后版本的 JVM 已经将运行时常量池从方法区中移了出来, 在 Java 堆 (Heap) 中开辟了一块区域存放运行时常量池.
JDK1.8 开始, 取消了 Java 方法区, 取而代之的是位于直接内存的元空间(metaSpace).
已知:
- String A="abc";
- String B="abc";
- String C=new String("abc");
- String D=new String("abc");
比较 A==B 是否相等?
比较 C==D 是否相等?
分析: 我们知道基本数据类型 (int,byte,char...) 这些是可以用 == 比较的, 因为他们没有地址, 只有值.
但 String 是类, 所以用 == 比较的时候, 判断的是地址是否相同, 所以这里 C 和 D 是不等, 他们是 new 出来的两个完全不同的对象, 仅仅是值相等, 就像是两个人仅仅是名字相同.
那么 A==B 吗?
A,B 并不是通过 new 的方式创建的, 所以他们的地址取决于后面所赋的值. Java 中, 普通字符串存储在常量池中, 常量池目前位于堆内存中, 所以, 从赋值方面来看, 此时的 A==B 是成立的, 比较的是常量池里的值.
总结: 一般对于对象, 比较值是否相等的时候, 都是通过覆写 equals 方法和 hash 方法来比较的, string 用的频繁所以这里是特例, 针对性的优化.
转载自: Java 字符串常量存放在堆内存还是 JAVA 方法区?
来源: http://www.bubuko.com/infodetail-3157005.html