总结: 基本类型的变量数据和对象的引用都是放在栈里面的,对象本身放在堆里面,显式的String常量放在常量池,String对象放在堆中。
-
常量池的说明
-
常量池之前是放在方法区里面的,也就是在永久代里面的,从JDK7开始移到了堆里面。这一改变我们可以从oracle的release version的notes里的** Important RFEs Addressed in JDK 7 **看到。
Area: HotSpot
Synopsis: In JDK 7, interned strings are no longer allocated in the permanent generation of the Java heap, but are instead allocated in the main part of the Java heap (known as the young and old generations), along with the other objects created by the application. This change will result in more data residing in the main Java heap, and less data in the permanent generation, and thus may require heap sizes to be adjusted. Most applications will see only relatively small differences in heap usage due to this change, but larger applications that load many classes or make heavy use of the String.intern() method will see more significant differences.
RFE: 6962931
String str1 = "123";
String str2 = "123";
-
第一句代码执行后就在常量池中创建了一个值为123的String对象;
-
第二句执行时,因为常量池中存在123所以就不再创建新的String对象了。
-
此时该字符串的引用在虚拟机栈里面。
String str3 = new String("321");
String str4 = new String("321");
-
Class被加载时就在常量池中创建了一个值为321的String对象,第一句执行时会在堆里创建new String("321")对象;
-
第二句执行时,因为常量池中存在321所以就不再创建新的String对象了,直接在堆里创建new String("321")对象。
验证
public static void main(String[] args) {
String str1 = "123";
String str2 = "123";
System.out.println(str1==str2); //true
String str3 = new String("321");
String str4 = new String("321");
System.out.println(str3==str4); //false
}
-
面试题:以下代码,创建了几个对象
-
答: 3个,字符串常量池中1个hello对象,堆内存中2个String对象
String str3 = new String("321");
String str4 = new String("321");
评论
222
hello
2021-07-23 回复
看什么看
hi2021-08-04 回复
test
HELLO2021-11-08 回复
test
你好
2021-11-08 回复
马四
捧个场2021-12-09 回复
rusell
很好!!!2021-12-27 回复
cal
很好!!!
2023-01-19 回复
谈涛
真的很不错2023-02-22 回复