最近在巩固Java基础知识,以此来加强一下。
Java有基础类型和引用类型,基础类型比较地址和内容可以直接用 ==。但是引用类型就不能行了,话不多说,直接上代码。
String s1 = "111";
String s2 = "111";
String s3 = new String("111");
System.out.println("s1 == s2:"+(s1==s2));
System.out.println("s1.equals(s2):"+s1.equals(s2));
System.out.println("s1 == s3:"+(s1==s3));
System.out.println("s1.equals(s3):"+s1.equals(s3));
大家猜一下输出结果是什么?
s1==s2 为true,是不是很不可思议。
这也是我在面试中遇到过的问题,那么是因为什么呢?
我们要先来理解一下 new String("111");和 = "111"; 的区别
下面引用我百度出来的答案:
String s1 = "111"是一种非常特殊的形式,和new 有本质的区别。
它是java中唯一不需要new 就可以产生对象的途径。
以 String s1="111"; 形式赋值在java中叫直接量,它是在常量池中而不是象new 一样放在压缩堆中。
这种形式的字符串,在JVM内部发生字符串拘留,即当声明这样的一个字符串后,JVM会在常量池中先查找有有没有一个值为"111"的对象,如果有,就会把它赋给当前引用。即原来那个引用和现在这个引用指点向了同一对象,如果没有,则在常量池中新创建一个"111",下一次如果有String s2 = "111"; 又会将s2指向"111"这个对象,即以这形式声明的字符串,只要值相等,任何多个引用都指向同一对象。
所以s1和s2实际上是指向的同一个对象。
String s1= "111"; 先在内存中找是不是有"111" 这个对象,如果有,就让s1指向那个"111"。如果内存里没有"111",就创建一个新的对象保存"111"。
String s3=new String ("111"); 就是不管内存里是不是已经有"111"这个对象,都新建一个对象保存"111"。
String s3= new String("111"); 是在堆里面建立的对象 String s3和"111"。
s1="111";是查找栈里有没有"111",如果有就用s1引用它,如果没有就把“111”存进栈。
String s1="111"; ---------------------生成一个对象 "111"
String s3=new String ("111"); ---------------生成两个对象,"s3"和new String ("111")
因为new String("111")的参数"111"本身就是一个字符串对象,new String("111")又返回一个字符串对象。