刚接触这个比较的时候完全被搞蒙了,一会儿值比较一会儿又地址比较,地址比较还又有多种情况,完全分不清,直接哭死。然后就来整理一波啦!!!
== 比较
==比较在用于基本类型比较时比较的是具体的值
补充:java的8大基本类型:byte short int long float double char boolean
接下来看具体的实例:
public static void main(String[] args) {
int a = 10;
int b = 20;
int c = 10;
int d = a;
System.out.println(a==b);//false,两个值不相等
System.out.println(a==c);//true
System.out.println(a==d);//true,将a赋值给d后,两个值均为10
System.out.println(c==d);//true
}
==比较在用于引用类型比较时比较的是存放在栈中的地址值即比较是否指向同一个对象
先直接上案例
String s1 = "123abc";
String s2 = "123abc";
System.out.println(s1==s2);//true,引用类型中==比较的是地址值,s1与s2是使用同一个地址值的
我们来看一下上面案例的内存图
从内存图中我们可以发现,我们的s1和s2都指向了同一个对象,栈中的地址值也是一样的。所以==比较后返回的值是true。
这里说一下这个字符串常量池:
java针对字符串给我们提供了一个优化措施:字符串常量池(在堆中)。即我们在使用字面量/直接量的方式来创建字符串时,会缓存所有以字面量形式创建的字符串对象,当使用相同字面量再次创建字符串时,系统会重用常量池中已有对象。上述的s2就是直接重用了s1存在常量池中的字面值,所有地址值相同。
拓展String的其他几种情况<也很重要>
1、
String s3 = new String("hello");
String s4 = "hello";
System.out.println(s3==s4);//false ,s与s3是两个对象
我们可以看到,此时s3与s4的值都是“hello”,但他==比较后的返回的是false。原因是String s3 = new String(“hello”);这句话他创建了两个对象,一个是字面值“hello”的对象,一个是new String()对象。而此处s2装的是new String()对象的地址,但s4装的是字面值的地址。地址不同,所有比较后返回的便是false。
2、
String s = "123";
String s1 = "123abc";
String s2 = "123abc";
s1 = s+"abc";//拼接后地址值发生改变
System.out.println(s1==s2);//false
此处第一个s1创建了一个字面值123abc并存放到了常量池中,所有s2创建的时候直接重用,两个的地址值相同。但后面s和abc拼接了一个123abc赋值给了s1,此时s1虽然值还是不变,但不再指向开始的常量值,所以最后比较时返回的是false。
3、
String s1 = "123abc";
String s2 = "123"+"abc";
System.out.println(s1==s2);//true
友友们看到这是不是开始疑惑了,这个和上一个差不多,为啥上一个是false,这个返回true?注意仔细观察两个案例的不同之处,上一个是拼接,这里是加法运算(这里不细说都是“+”,为啥上面是拼接,这是算法)。编译器在编译时,若发现一个计算表达式可以在编译的时候就确定结果,则直接运算好并将结果保存到表达式中,在参与运算。所以,s2进入内存是已经是“123abc”了,他会直接重用s1的值,故比较时地址值相同,返回true。
4、
String s5 = "hello";
String s6 = s5;
System.out.println(s5==s6);//true
String s7 = new String("hello");
String s8 = s7;
System.out.println(s7==s8);//true
上述两种情况是一致的,这里就只说明第一个了哦!
在java中,字符串一旦创建,其中的值将无法改变,所以s5赋值给s6的就是同一个值,同一个地址。故比较得到的是true结果。
到这就暂时结束啦!欢迎友友们在评论区给出宝贵意见一起成长哦!