对于初学Java而言,很多同学搞不清==和equals()的区别,下面带大家一起来见证奇迹得时刻。
==:
== 比较的是变量(栈)内存中存放的对象(堆)内存地址,用来判断两个对象的地址是否相同,即是否是指向同一个对象,比较的是真正意义上的指针操作。
== 可以比较基本类型,比较的是值。
创建Person类
import java.io.Serializable;
/**
* ClassName:Person <br/>
*
* Function: TODO ADD FUNCTION. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2019年4月11日 上午11:27:15 <br/>
*
* @author Administrator
* @version
* @since JDK 1.8
* @see
*/
public class Person implements Serializable {
/**
* serialVersionUID:TODO
*
* @since JDK 1.8
*/
private static final long serialVersionUID = 1L;
private String name;
private int id;
private char gender;
private String address;
private int age;
public Person() {
super();
}
public Person(String name, int id) {
super();
this.name = name;
this.id = id;
}
public Person(String name, int id, char gender, String address, int age) {
super();
this.name = name;
this.id = id;
this.gender = gender;
this.address = address;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public char getGender() {
return gender;
}
public void setGender(char gender) {
this.gender = gender;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", id=" + id + ", gender=" + gender + ", address=" + address + ", age=" + age
+ "]";
}
}
创建测试类
/**
* ClassName:TestPerson <br/>
*
* Function: TODO ADD FUNCTION. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2019年4月17日 上午8:06:17 <br/>
*
* @author Administrator
* @version
* @since JDK 1.8
* @see
*/
public class TestPerson {
public static void main(String[] args) {
int a = 10;
long b = 10l;
double c = 10.d;
float f = 10f;
// 比较的是地址,数字的值相等就为true,因为他们指向地址为10的堆
System.out.println(a == b);// true
System.out.println(a == c);// true
System.out.println(a == f);// true
System.out.println(c);
Person p1 = new Person("小强", 888888);
Person p2 = new Person("小强", 888888);
// 采用等号比较引用类型比较的是引用类型的地址(地址也是值)
// 我们比较的应该是对象的具体属性
System.out.println(p1 == p2);// false
Person p3=p1;
//p1和p3指向的是一个对象,所以地址一样,采用等号比较引用类型比较的是地址
System.out.println(p1==p3);//true
String s1="String";
String s2="String";
//==两端的操作数是否是同一个对象
System.out.println(s1==s2);//true
}
}
equals:
采用equals比较两个对象的内容是否相等,由于所有的类都是继承Object类,所以适用于所有对象,若是没有对方法进行重写的话,调用的仍然是Object类中的方法,而Object中的equals方法返回的==的判断。
/**
* ClassName:EqualsTest02 <br/>
*
* Function: TODO ADD FUNCTION. <br/>
* Reason: TODO ADD REASON. <br/>
* Date: 2019年4月17日 下午2:51:44 <br/>
*
* @author Administrator
* @version
* @since JDK 1.8
* @see
*/
public class EqualsTest02 {
public static void main(String[] args) {
String s1 = "chinasoft";// 存放于常量池中
String s2 = "chinasoft";// 从常量池中去查找
System.out.println(s1 == s2);// true
System.out.println(s1.equals(s2));// true
String s3 = new String("chinasoft");// s3表示一个引用
String s4 = new String("chinasoft");// s4表示另外一个引用,对象的内容与s3一样
System.out.println(s3 == s4);// false
System.out.println(s3.equals(s4));// true
}
}
String s="abce"是一种非常特殊的形式,和new 有本质的区别。它是java中唯一不需要new 就可以产生对象的途径。以String s="abce";形式赋值在java中叫直接量,它是在常量池中而不是象new一样放在压缩堆中。这种形式的字符串,在JVM内部发生字符串拘留,即当声明这样的一个字符串后,JVM会在常量池中先查找有有没有一个值为"abcd"的对象,如果有,就会把它赋给当前引用.即原来那个引用和现在这个引用指点向了同一对象,如果没有,则在常量池中新创建一个"abcd",下一次如果有String s1 = "abcd";又会将s1指向"abcd"这个对象,即以这形式声明的字符串,只要值相等,任何多个引用都指向同一对象.而String s = new String("abcd");和其它任何对象一样.每调用一次就产生一个对象,只要它们调用。
也可以这么理解: String str = "hello"; 先在内存中找是不是有"hello"这个对象,如果有,就让str指向那个"hello".如果内存里没有"hello",就创建一个新的对象保存"hello". String str=new String ("hello") 就是不管内存里是不是已经有"hello"这个对象,都新建一个对象保存"hello"
于是又有这样的问题。对于身份证相同,名字一致的Person对象肯定是同一个对象,而测试发现是不同的对象。
Person p1=new Person(421125, "zs");
Person p2=new Person(421125, "zs");
System.out.println(p1.equals(p2));//false
System.out.println(p1==p2);//false
对象比较都是采用equals方法,但这是Object类的方法,底层采用==来判断,所以以上输出的结果都为false
我们应该根据自己的规则来判断,身份证相同,名字一致表示同一个对象,必须要重写父类的equals方法,所以在Person类中重写equals方法
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof Person) {
Person p = (Person) obj;
if (this.id == p.id && this.name == p.name) {
return true;
}
}
return false;
}
Person p1=new Person(421125, "zs");
Person p2=new Person(421125, "zs");
System.out.println(p1==p2);//false
System.out.println(p1.equals(p2));//true
equals()和==的区别
由equals的源码可以看出这里定义的equals与==是等效的(Object类中的equals没什么区别),不同的原因就在于有些类(像String、Integer等类)对equals进行了重写,但是没有对equals进行重写的类(比如我们自己写的类)就只能从Object类中继承equals方法,其equals方法与==就也是等效的,除非我们在此类中重写equals
"=="比"equals"运行速度快,因为"=="只是比较引用