Java中==与equals方法的区别
1.==
==
只用于以下两种场景:
- 01.操作符专门用来比较两个变量的值是否相等,也就是用于比较变量所对应的内存中所存储的数值是否相同,要比较两个基本类型的数据或两个引用变量【什么是引用变量?见02分析】是否相等,只能用 == 操作符。
- 02.如果一个变量指向的数据是对象类型的,那么这时候就涉及了两块内存,对象本身占用一块内存(堆内存),变量也占用一块内存,例如
Objet obj = new Object();
变量 obj占用一个内存,new Object()占用另一个内存,此时,变量obj所对应的内存中存储的数值就是对象占用的那块内存的首地址。对于指向对象类型的变量,如果要比较两个【引用】变量是否指向同一个对象,即要看这两个变量所对应的内存中的数值是否相等,这时候就需要用 == 操作符进行比较。
equals
- 1.equals方法是用于比较两个独立对象的内容是否相同,它比较的两个对象是独立的。[潜在的说,就是已经明确这是两个不同的对象了,如果使用==测试,肯定为false。但是还不知道他们所指的对象变量是否相等,这个时候就可以使用equals了]
String a = new String("LittleLawson");
String b = new String("LittleLawson");
两条 new 语句创建了两个对象,然后用 a/b这两个引用变量分别指向了其中的对象,这是两个不同的对象,它们的首地址是不同的,即 a 和 b 中存储的数值是不相同的,所以,表达式 a==b 将返回 false ,而这两个对象中的内容是相同的,所以,表达式 a.equals(b)将返回true 。因为上述原因,字符串的比较基本上都是使用equals方法。
- 2.如果一个类没有自己定义的equals方法,那么它将继承Object类的equals方法,Object类的equals方法的实现如下:
boolean equals(Object o){
return this==o;
}
可以看到原生的equals
方法就是直接比较两个对象中的值是否为相同。
注:
- 经典代码1:为什么基本数据类型就是比较内容,而对象就是比较地址?
参考享元模式,避免大量拥有相同内容对象的内存开销。
Integer i1 = 20;
Integer i2 = 20 ;
System.out.println(i1 == i2); // true
Integer i3 = 200;
Integer i4 = 200 ;
System.out.println(i3 == i4); // false
Integer i1 = 20;
其实是一个自动装箱的过程,编译器会自动展开成Integer i = Integer.valueOf(20);
详情可以看Integer.valueOf的源代码,可以看到参数的值在IntegerCache.low(默认-128) 到 IntegerCache.high(默认127)
范围内时(比如20),会从IntegerCache.cache中直接取(此处参考Integer的内部类IntegerCache的源代码,如果不配置的话,默认是cache存储-128到127的Integer),所以取到的都是同一个Integer的对象,因此相同。而200不在-128到127范围内,所以会new 一个新的Integer,故不相同。
- 经典代码2:引用于对象的区别
Person p = new Person();
Person p1 = p;
sout(p.equals(p1))
p与p1这些都是引用变量,他们指向的是同一个对象【new Person()】