一、==和equals区别
是否指向同一个对象
重写equals
package com.instanceOf.java;
//A是B父类,B是C父类
public class A {
int a;
public A(int a) {
super();
this.a = a;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}
package com.instanceOf.java;
public class B extends A{
int b;
public B(int a, int b) {
super(a);
this.b = b;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
//重写equals方法,在ABCTest方法中传递过来的实参其实是C创建的对象
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(obj instanceof B) {// C是B子类,所以这里返回值是True
B test1 = (B)obj;//将C创建的对象(类型是A)向下转型为B
return this.b == test1.b && this.a == test1.a;//比较以B为准
}
return false;
}
}
package com.instanceOf.java;
public class C extends B{
int c;
public C(int a, int b, int c) {
super(a, b);
this.c = c;
}
public int getC() {
return c;
}
public void setC(int c) {
this.c = c;
}
}
package com.instanceOf.java;
public class ABCTest {
public static void main(String[] args) {
A test = new B(1,2);
A test1 = new C(1,2,3);
A test2 = new B(1,2);
boolean isEquals = test.equals(test1);//test1中有1,2,3,test中有1,2,显然不同
//但,在B中重写的equals中没有比较3,所以返回的是true
if(isEquals) {
System.out.println("相等");
}else {
System.out.println("不相等");
}
boolean isEquals1 = test.equals(test2);//我这里所重写的equals显然,只要后者有和前者重合的地方就认为相等
//(前提是后者所属类是前者所属类或其子类)
if(isEquals1) {
System.out.println("相等");
}else {
System.out.println("不相等");
}
}
}
输出结果:
相等
相等
修改后
package com.instanceOf.java;
public class B extends A{
int b;
public B(int a, int b) {
super(a);
this.b = b;
}
public int getB() {
return b;
}
public void setB(int b) {
this.b = b;
}
//重写equals方法
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(obj.getClass() == this.getClass()) {//只能传进来B类型变量
B test1 = (B)obj;
return this.b == test1.b && this.a == test1.a;
}
return false;
}
}
输出结果:
不相等
相等
可以自动生成,但感觉有点问题:没有判断a
生成时提示:
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
B other = (B) obj;
return b == other.b;
}
修改后
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
B other = (B) obj;
return b == other.b && a == other.a;//后面a是自己补充的
}
练习
package com.test.java;
public class Order {
int orderId;
String orderName;
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;
}
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
public Order(int orderId, String orderName) {
super();
this.orderId = orderId;
this.orderName = orderName;
}
public boolean equals(Object obj) {
if (this == obj)//指向同一个对象,TRUE
return true;
if (obj == null)//是null,TRUE
return false;
if (getClass() != obj.getClass())//不是同一个类型,FALSE
return false;
Order other = (Order) obj;
return orderId == other.orderId && orderName.equals(other.orderName) ;
}
}
package com.test.java;
public class OrderTest {
public static void main(String[] args) {
Order test = new Order(1001,"张三");
Order test1 = new Order(1002,"李四");
Order test2 = new Order(1001,"张三");
System.out.println("test和test1是否相等:" + test.equals(test1));
System.out.println("test和test2是否相等:" + test.equals(test2));
}
}
重写equals时,orderName == other.orderName,也是正确的,原因:
String内容存在常量池中,而常量池中在第一句中放入一个“张三”,第二句执行时不再创建,而是将“张三”复用,所以str和str1地址是一样的,返回TRUE
但是最好用equals,因为如果字符串是创建的对象new String(),就会放在堆里,就没有复用了