涉及三块区域:栈,堆,字符串常量池(jdk1.7之前在方法区,jdk1.7之后在堆中)
关于字符串常量池到底在不在堆中:
jdk1.6及以前,方法区独立存在(不在堆里面),字符串常量池存在方法区
jdk1.7及以后,字符串常量池被移到堆中
两种创建字符串的方式:
1.直接创建 String s="test"
只在栈中创建一个对象,堆中不创建对象
这个栈对象中保存的就是字符串的地址
2.new的方式创建 String s=new String("test")
总共创建两个对象,栈中创建一个对象,堆中创建一个对象
堆中对象保存的是字符串的地址,栈中对象保存的是堆中对象的地址,所以栈中对象保存的是地址的地址
String s1 = new String("abc") 这句代码创建了几个对象?
答案:1个或者2个
其实就是问栈和堆里面总共有几个对象
如果堆里面已经有一个对象保存了“abc“这个对象的地址,那就只需要在栈中创建一个对象,保存堆中对象的地址即可,所以只需要创建一个对象
如果没有,那就要创建两个对象,先在堆中创建一个对象,保存字符串的地址,然后再在栈中创建一个对象,保存堆中对象的地址,总共创建两个对象
public class StringTest
{
public static void main(String[] args)
{
String str1 = "abc";
String str2 = "abc";
String str3 = new String("abc");
String str4 = new String("abc");
System.out.println(str1 == str2); //true
System.out.println(str1 == str3); //false
System.out.println(str1.equals(str3)); //true
System.out.println(str3 == str4); //false
}
}
第一个: str1和str2这两个对象里面存的都是字符串中的地址,所以是true
第四个:new一次就要在堆中创建一个新对象,所以str3和str4存的堆中对象地址不相等