一.概念
栈:存放基本数据类型的变量和对象的引用
堆:存放new出来的对象(存放对象实例和数组,GC 管理的主要区域。)
常量池:顾名思义,存放字符串常量和基本数据类型常量(public static final)
静态域:顾名思义,存放静态成员(static定义的)
- 栈和常量池中的对象可以共享,堆中的对象不能共享。
- 栈中的数据大小和生命周期是可以确定的,当没有引用指向数据时,这个数据就会消失
- 堆中的对象的由垃圾回收器负责回收,因此大小和生命周期不需要确定,具有很大的灵活性。
- 对于字符串:其对象的引用都是存储在栈中的,如果是编译期已经创建好(直接用双引号定义的)的就存储在常量池中,如果是运行期(new出来的)才能确定的就存储在堆中。对于equals相等的字符串,在常量池中永远只有一份,在堆中有多份。
二.图示
String str = “abc"创建对象的过程
1 首先在常量池中查找是否存在内容为"abc"字符串对象
2 如果不存在则在常量池中创建"abc”,并让str引用该对象
3 如果存在则直接让str引用该对象
也就是有道面试题: String s = new String(“abc”); 产生几个对象?
一个或两个。如果常量池中原来没有 ”abc”, 就是两个。如果原来的常量池中在“abc”时,就是一个。
String s1 = “china”;
String s2 = “china”;
String s3 = “china”;
String ss1 = new String(“china”);
String ss2 = new String(“china”);
String ss3 = new String(“china”);
最后,说明一道经典的面试题
public class Test {
public static void main(String[] args) {
String a = "abc";
String b = "abc";
String c = new String("abc");
String d = "ab" + "c";
System.out.println("a == b" + a == b); //true
System.out.println("a == c" + a == c); //false
System.out.println("a == d" + a == d); //true
System.out.println("b == c" + b == c); //false
System.out.println("b == d" + b == d); //true
System.out.println("c == d" + c == d); //false
}
}
==比较的是地址,a,b,c都是指向相同常量值的同一个地址,c是new出来的指向堆的地址
转载:https://blog.csdn.net/lk274857347/article/details/77512555