java中创建String类型对象有两种方式
1.String a="***";
2.String a=new String ("***");
两者创建相同的字符串在内存中的地址却是不一样的,如下面的代码所示:
public static void StringTest(){
String s1="abc";
String s2="abc";
String s3=new String("abc");
System.out.println("s1 == s2 :"+(s1==s2));//true
System.out.println("s2 == s3 :"+(s3==s2));//false
}
如上面的代码所示,s1==s2返回true;而s3==s2返回false,这是为什么呢?
内存如图所示:
为了提高效率,java在内存中定义了字符串常量池,当通过String s1="abc"的方式创建字符串的时候,首先会去常量池中查看是否有"abc"字符串,如果没有则直接在字符串常量池中创建"abc",并且将该内存地址赋值给s1;当执行代码String s2="abc"的时候,同理先去字符串常量池中查看是否有"abc"字符串,由于创建s1的时候已经在常量池中创建了"abc"所以这个时候直接将"abc"的内存地址返回给s2,所以s1==s2为true
当通过String s3=new String("abc")的方式创建字符串的时候,因为通过new方法创建对象是直接在堆内存中分配空间用来创建字符串的,详细过程分为两步:
1.检查字符串常量池中是否有"abc"字符串,如果没有则在常量池中创建"abc",有则不创建
2.在堆中分配空间用来创建"abc"对象并且将该内存地址赋值给s3
所以s3==s2返回false(堆内存地址不等于常量池地址)