我们都知道,Java中数据类型大体上可分为两类:基本数据类型和引用数据类型。equals和==都是用来比较数据与数据是否“相等”。
基本数据类型的比较
基本数据类型之间的比较用“==”,用来判断它们的值是否相等。
示例代码:
public class Test{ public static void main(String[] args){ int i1=9; int i2=9; boolean b1=true; boolean b2=true; char c1='c'; char c2='c'; System.out.println(i1==i2); //输出为true System.out.println(b1==b2); //输出为true System.out.println(c1==c2); //输出为true } }
基本数据类型之间的比较不用equals。
引用数据类型的比较
引用类型之间既可用“==”来比较,又可以用equals来比较。
用“==”来比较引用对象
用“==”来比较引用对象的时候,比较的是他们的地址,即在栈中存放的变量值。
public class Test{ public static void main(String[] args){ Person p1=new Person("Danny",24); Person p2=p1; Person p3=new Person("Danny",24); System.out.println(p1==p2); //输出为true System.out.println(p1==p3); //输出为false } } class Person{ public String name; public int age; public Person(String name,int age){ this.name=name; this.age=age; } }
这时的内存图为:
p1和p2都指向同一个对象,所以p1和p2中存放的地址是一样的,而“==”比较的正是他们在栈中存放的值,所以p1==p2的值为True; p3和p1指向的对象虽然一模一样,但是不是同一个对象,所以p1!=p3(或者p1==p3==false)。
特殊情况,
对于String和Integer来说,创建对象的方式不同,用“==”比较的结果是不同的,比如:
public class Test{ public static void main(String[] args){ String a1="hello"; String a2="hello"; String a3=new String("world"); String a4=new String("world"); System.out.println(a1==a2); //输出为true System.out.println(a3==a4); //输出为false } }
用equals来比较引用类型
在基类Object中定义了equals方法,这个方法比较的也是对象的内存地址,即上例中如果把“p1==p2”换成p1.equals(p2),结果也是一样的。
特殊情况,
如果一个类没有自己定义equals方法,它默认的equals方法(从Object类继承的)就是使用==操作符,也是比较两个变量指向的对象是否是同一个对象,这时候使用equals和使用==会得到同样的结果。
但有些类重写了Object类中的方法,这时它比较的是所指对象的内容是否相同。比如:
public class Test{ public static void main(String[] args){ String a1="hello"; String a2="hello"; String a3=new String("hello"); String a4=new String("hello"); System.out.println(a1==a2); //输出为true System.out.println(a3==a4); //输出为false System.out.println(a1.equals(a4)); //输出为true } } class Person{ public String name; public int age; public Person(String name,int age){ this.name=name; this.age=age; } }
上面的a1和a4显然不是指向同一个对象,但它们所指对象中的内容相同,所以a1.equals(a4)的值为true。