目录
栗子3:直接调用Object类以外的类的equals()方法的效果
==运算符
==运算符的使用说明
- ==运算符可以在基本数据类型中使用,也可以在引用数据类型中使用
- ==运算符在基本数据类型中使用时(即表达式的两边都是一个基本数据类型),表示比较这两个变量的值(或者说是内容)是否是相等的
- ==运算符在引用数据类型中使用时(即表达式的两边都是一个引用数据类型),表示比较两个引用数据类型对象的地址是否相同。
栗子1:==运算符用于基本数据类型
看下面的代码段
public class demo_2 {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println(a == b); //false
int c = 10;
System.out.println(a == c); //true
}
}
当执行a==b时,判断的是a和b的值是否相等,此处a的值为10,b的值是20,a和b的值不相等,因此输出false
当执行a==c时,判断的是a和c的值是否相等,此处a的值为10,c的值为10,a和c的值相等,因此输出true
栗子2:==运算符用于引用数据类型
看下面的代码段
public class demo_2 {
public static void main(String[] args) {
String str1 = "str";
String str2 = "str";
String str3 = new String("str");
System.out.println(str1 == str2); //true
System.out.println(str1 == str3); //false
}
}
创建了三个变量str1、str2、str3,都是String类型,都是引用数据类型
当执行str1 == str2时,在字符串常量池中已经存在了一个字符串,内容为str。str1指向的是字符串str所在的内存单元的地址,str2指向的也是字符串str所在的内存单元的地址,因此比较的结果是true
当执行str1 == str3时,str1指向的是字符串str所在的内存单元的地址,但是对于str3而言,虽然内容也是字符串str,但是str3是通过new关键字创建的String类的对象,因此str3指向的是堆中的某一个内存单元地址,因此比较的结果是false
equals()方法
equals()方法的使用说明
- 仅可用于引用数据类型
- 在Object类中,默认定义了equals()方法,但默认定义的equals()方法的效果和==运算符的效果是相同的,都是比较两个引用数据类型的地址是否相等,而并不是比较两个引用数据类型的内容是否相等
- 因此,自己创建的类,若是没有在类中重写equals()方法,那么直接调用equals()方法进行判断的效果和使用==运算符进行判断的效果是相同的(因为自己创建的类的根父类都是Object类)
- 但是对于Object类以外的类而言,直接调用equals()方法判断的是两个引用数据类型的内容是否相等而并非地址是否相等,因为对于Object以外的类,它们都重写了equals()方法
栗子1:创建一个类并且不重写equals()方法
看下面的代码段
public class demo_2 {
int age;
public demo_2(int age) {
this.age = age;
}
}
public class demo_3 {
public static void main(String[] args) {
demo_2 d1 = new demo_2(1);
demo_2 d2 = new demo_2(1);
System.out.println(d1 == d2); //false
System.out.println(d1.equals(d2)); //false
}
}
创建了两个demo_2类型的对象d1、d2,它们都只有一个age属性并且属性值都是1。
执行d1 == d2时,对于引用数据类型,==运算符比较的是两个引用数据类型的地址。d1和d2是通过new关键字创建的对象,因此比较的结果是false
执行d1.equals(d2)时,对于引用数据类型,自己创建的类若是没有重写euqals()方法,效果和==运算符相同,因此比较的结果也是false
栗子2:创建一个类并且重写equals()方法
看下面的代码段
public class demo_2 {
int age;
public demo_2(int age) {
this.age = age;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
demo_2 demo2 = (demo_2) o;
return age == demo2.age;
}
}
public class demo_3 {
public static void main(String[] args) {
demo_2 d1 = new demo_2(1);
demo_2 d2 = new demo_2(1);
System.out.println(d1 == d2); //false
System.out.println(d1.equals(d2)); //true
}
}
在之前代码段的基础上重写了equals()方法
此时执行d1 == d2,得到的仍然是false,因为两个对象的地址是不相同的
此时执行d1.equals(d2),因为重写了equals()方法,因此调用的是重写后的方法,得到的结果是true
栗子3:直接调用Object类以外的类的equals()方法的效果
此处以String类为例
先来看一下String类是否继承了Object类:
很明显,String类继承了Object类
再看一下String类的结构:
可以发现String类重写了equals()方法
再看一下String类重写的equals()方法的内容:
现在通过一段代码来验证一下String类调用equals()方法比较的是否是内容
public class demo_3 {
public static void main(String[] args) {
String str="1";
String str1=new String("1");
System.out.println(str==str1);
System.out.println(str.equals(str1));
}
}
执行str == str1时,由于str指向的是常量池的地址,str1指向的是堆中的地址,因此两者并不相等,得到了false
执行str.equals(str1)时,虽然二者指向的地址不相同,但是二者的内容相同,因此得到了true