一、基础
Java当中所有的类,都继承于Object这个基类,Object中定义了一个equals方法,用来比较对象的内存地址,此时 == 的作用与 equals方法的作用是相同的。
但是,在一些类库(如:String、Integer、Date)中,equals方法被覆盖掉了,这些类库中的equals方法被用来比较对象的内容是否相同。
所以,对于Object基类,equals方法和 == 都是用来比较对象的内存地址是否相同的。
二、扩展
1、Java中的数据类型分为两类:
(1)基本数据类型(原始数据类型):byte、short、char、int、long、float、double、boolean
(2)引用数据类型:String,各种对象
2、==
(1)对于基本数据类型,比较的是值是否相同
(2)对于引用数据类型,比较的是内存地址是否相同
3、equals方法
(1)若未被重写,比较的是内存地址是否相同
(2)若已被重写,比较的是值或对象的内容是否相同
三、题目
// 基本数据类型的比较,比较的是值是否相同
int num1 = 10;
int num2 = 10;
System.out.println(num1 == num2); //true
// 引用数据类型比较,比较的是内存地址是否相同
Student stu1 = new Student();
Student stu2 = new Student();
System.out.println(stu1 == stu2); //false
System.out.println(stu1.equals(stu2)); //false
// new出来了两个对象,内存地址一定不同
String a = "abc";
String b = "abc";
System.out.println(a == b); //true
// a代表的"abc"在常量池中,b代表的"abc"已经存在于常量池中,
// 所以b指向已存在的"abc",a和b的内存地址相同
System.out.println(a.equals(b)); //true
// String类库中,对equals方法进行了重写,此时equals方法比较的是两个字符串对象的内容是否相同
String a = new String("a");
String b = new String("a");
System.out.println(a == b); //false
// String是引用数据类型,此时 == 比较的是内存地址是否相同,new出来的两个对象,内存地址一定不同
System.out.println(a.equals(b)); //true
// a和b字符串的内容相同
String s1 = "Monday";
String s2 = new String("Monday");
System.out.println(s1 == s2); //false
// 比较内存地址是否相同,s1在常量池中,s2在堆(heap)内存中,内存地址不同
System.out.println(s1.equals(s2)); //true
// 两个字符串内容相同
String s1 = "ab";
String s2 = "cd";
String s3 = s1 + s2;
String s4 = "abcd";
System.out.println(s3.equals(s4)); //true
System.out.println(s3 == s4); //false
// s1、s2、s4 均在常量池当中,
// s3的执行过程是:JVM在堆中创建一个StringBuilder类,用s1指向的字符串完成初始化,
// 调用append()方法完成对s2所指向的字符串的合并操作,
// 调用StringBuilder的toString()方法在堆中创建一个String对象,
// 将生成的String对象的堆地址,存放在变量s3中,
// 因此s3和s4的内存地址不同