简要分析==和equals的区别
1.Java中有两种类型的比较,一种是值类型比较,一种是引用数据类型比较。
2.值类型的比较可以直接使用==,但是==
无法直接比较引用数据类型(有特例),因为==
是方法中的操作符,当使用引用数据类型创建对象的时候是在堆中开辟地址空间,方法是进入栈中的,由栈中的对象指向堆中的空间是地址值的传递,所有当有两个调用new关键字开辟了空间的对象用==进行比较时,是比较的地址值,一定是false,是不能直接比较对象内容的。(浅拷贝的对象是相同地址,引用相同,没有比较的意义)
3.特例就是String类型的字符串是存放在方法区中的字符串常量池里,相同面值访问同一个常量池,不会重复创建,地址是一样的,不同面值则会创建新的常量池,可以使用==
直接比较,并且与equals方法比较结果无差别。
4.当然如果你愿意也可以把两个对象的内容一一列出,在方法中使用==
依次比较。但不建议这么做,因为当你创建新的对象进行比较的时候又得写很多相应的代码。
5.因此我们可以使用equals方法来提高代码的复用性,Object提供的equals方法的底层源码还是用的==,比较的地址值,因此我们需要在其子类中进行equals方法的重写来覆盖Object的equals方法,把对象中比较的内容列在equals方法中。当然你愿意也可以自己命名定义一个方法。也不建议这么做,因为在不同类中使用你定义的那个方法又得创建对象来调用,浪费资源。
6.那么equals方法写在哪个子类中好呢?我个人建议写在抽象类中,因为继承的传递性,其他类继承后,可以实现不同的类调用新写的equals方法,这样需要使用的时候就不用每个类都重写了。
7.(涉及关于equals方法重不重写问题)
验证代码我也上传一下:`
package frist_package;
public class test14 {
public static void main(String[] args) {
a0 x = new a0();
b0 y = new b0();
String z = "l岱x";
String w = "d岱";
System.out.println(x.equals(y)); //比较的是两个对象,两个对象属性我调的一模一样,证明需要重写equals方法。
System.out.println("****************");
//String类型的比较(与==一样的结果)
System.out.println(z.equals("l岱x"));
System.out.println(z=="l岱x");
System.out.println("****************");
System.out.println(z.equals("d岱"));
System.out.println(z=="d岱");
System.out.println("****************");
System.out.println(z.equals(w));
System.out.println(z==w);
}
}
class a0{
int a=2;
String b="a";
static int c=3;
}
class b0{
int a=2;
String b="a";
static int c=3;
}
验证代码运行结果:
8.对于这两个结果我找了一下底层源码
(1)两个对象比较的底层源码<这个就需要重写>
(2)String字符串比较的底层源码<这个不需要重写>
<说明String字符串比较时==和equals方法结果无差别,使用什么都行,不需要重写equals方法>
9.equals方法重不重写主要是看比较的对象是什么。注意基本数据类型(也就是值类型不可以直接使用equals方法,因为Object没提供,但是你可以自己写一个。)