我们知道JVM分三块内存区域——栈、堆和方法区
java中的数据类型分——引用数据类型和基本数据类型
String属于引用数据类型,那么创建的字符串存在哪里呢?例如对以下代码进行内存分析:
public class TestString01 {public static void main(String[] args) {String s1 = "asd"; String s2 = "asd" + "jkl"; String s3 = new String("jkl"); }}
我们首先要知道,双引号括起来的字符串存储在字符串常量池中,字符串常量池又存在于方法区当中,所以像常量一样,java中字符串一旦创建不可改变,即“asd”储存在方法区当中不能被修改,这种机制的存在,提高了执行效率,例如上述代码中,定义s1和s2时,就在字符串常量池中开辟了三块空间,分别存储"asd"、“jkl"和"asdjkl”,在再创建s3对象时,就可以直接用现成的,不需要重新新开辟空间存储“jkl”,上面代码内存图如下所示:
试分析以下代码的执行效果:
public class TestString01 { public static void main(String[] args) { String s1 = "hello"; String s2 = "hello"; String s3 = new String("word"); String s4 = new String("word"); System.out.println(s1 == s2); System.out.println(s3 == s4); }}
我们可以通过画内存图更加直观的知道:
如图可知,s1和s2存储的地址相同,所以第一个输出为true,s3和s4存储的是堆里面的两个String对象的内存地址,虽然堆里面的两个String对象存储的两个内存地址相同,但栈里面s3和s4里面存储的内存地址不一样,所以第二个输出为false。
试分析以下代码创建了几个对象:
public class TestString01 { public static void main(String[] args) { String s3 = new String("word"); String s4 = new String("word"); }}
正确答案是三个,堆里面两个和字符串常量池里面一个。