==和equals()恐怕是刚刚开始学习Java中,最让人混淆的东西了。下面就可以
在Java程序设计中,我们经常需要比较两个变量值是否相等,比如:
a = 10;
b = 12;
if(a == b) {
//statements
}
再如:
ClassA a = new ClassA(“abc”);
ClassA b = new ClassA(“abc”);
if (a == b){
//statements
}
对于第一个例子,比较的是简单类型数据,它们是明显相同的,所以a==b这个值为true。
但是,对于第二个例子中的比较表达式,因为它们比较的是这两个变量a和b是否指向同一个对象引用,在这里,因为a指向一个对象,而b指向另一个对象,所以,它们并不指向同一个对象,因此,a==b返回的值是false。
为了方便说明简单类型和引用类型比较,此处用int类型和它的封装类Integer来说明简单类型和封装类型的进行比较时的区别。
我们来看下面的例子。
public class TestEqual {
public static void main(String[] args) {
// 简单类型比较
int a = 100;
int b = 100;
System.out.println("a==b? " + (a == b));
// 引用类型比较
Integer c = new Integer(100);
Integer d = new Integer(100);
System.out.println("c==d? " + (c == d));
}
}
运行这个程序,在控制台上打印出如下信息:
a==b? true
c==d? false
// 其他属性略
public Citizen(String theId) {
id = theId;
}
}
可以看出,比较两个引用类型的时候,虽然用了同一个参数构造两个变量,但是它们并不相同。这是为什么呢?
我们知道,对于引用类型,它们指向的是两个不同的对象:这两个对象的值都为100。因为它们指向的对象是两个对象,因此,比较这两个变量会得到false的值。也就是说,对于引用类型变量,运算符“==”比较的是两个对象是否引用同一个对象。
那么,如何比较对象的值是否相等?
在Java中,提供了一个equals()方法,用于比较对象的值。我们将上面的程序稍作修改:
Integer c = new Integer(100);
Integer d = new Integer(100);
System.out.println("c equals d? "+(c.equals(d)));
这个时候表达式c.equals(d)会得到一个true,这是因为,方法equals()进行的是“深层比较”,它会去比较两个对象的值是否相等。
那这个equals()方法是由谁来实现的呢?在所有类的父类Object中,已经定义了一个equals()方法,但是这个方法实际上也只是测试两个对象引用是否指向同一个对象。
所以,你可以使用这个方法来进行比较操作,但是,它并不一定能得到你所期望的效果。经常的,还需要自己将定义的类中的equals()进行覆盖。象Integer封装类,就覆盖了Object中的equals()方法。
关于==和equals()两种比较方式,在使用的时候要小心的选择:如果测试两个简单类型的数值是否相等,则一定要使用“==”来进行比较;
如果要比较两个引用变量对象的值是否相等,则用对象的equals()方法来进行比较;如果需要比较两个引用变量是否指向同一个对象,则使用“==”来进行比较。对于自定义的类,应该视情况覆盖Object或其父类中的equals()方法。equals()方法只有在比较的两者是同一个对象的时候,才返回true。
覆盖equals()方法
Object类的equals()方法的用处是用于测试两个对象引用是否是指向同一个对象。这种比较方式在实际应用中并没有多大的用处:我们常常需要的是判断两个对象的值是否相等而并不关心它们是否指向同一个对象。因此,需要在自己定义的类中对它进行覆盖。
我们来考虑如下的这种场景:假设在一个Java应用程序中,创建了两个“公民”对象。现在,我们需要比较两个“公民”对象是否相等,此时,关心的是这两个“公民”对象代表的是否为同一个人,而并不关心它们是否是同一个内存区域里的对象。
假设有一个类“Citizen”用于表示公民,它有一个属性id用来表示这个公民的身份证号,我们假设身份证号不会重复,也就是说,一个身份证号对应一个公民。它的类定义如下(为简单起见,省略了其他的属性而只留下用于表示身份证号的id属性):
public class Citizen {
// 身份证号
String id;
// 其他属性略
public Citizen(String theId) {
id = theId;
}
我们假设在一个Java应用程序中,建立了两个“Citizen”对象,然后,在某个点上需要判断这两个对象是否代表了同一个公民:
Person p1 = new Person("id00001");
Person p2 = new Person("id00001");
... ...
if (p1.equals(p2)){
... ...
}
在这个程序中,因为这两个“Citizen”对象的身份证号一样,所以,它们代表的应该是同一个人,但如果用Object的默认方式,它只会去比较两个对象引用变量是否指向同一个对象,因此,它返回false。
显然,这个结果不是我们所期待的。此时,就需要在“Citizen”中覆盖Object类中的equals()方法,以满足我们自己的需求。
public class Citizen {
// 身份证号
private String id;
// 覆盖equals方法
public boolean equals(Object obj) {
// 首先需要判断需要比较的obj是否为null,
// 如果为null,返回false
if (obj == null) {
return false;
}
// 判断测试的是否为同一个对象,
// 如果是同一个对象,无庸置疑,它应该返回true
if (this == obj) {
return true;
}
// 判断它们的类型是否相等,
// 如果不相等,则肯定返回false
if (this.getClass() != obj.getClass()) {
return false;
}
// 将参数中传入的对象造型为Citizen类型
Citizen c = (Citizen) obj;
// 只需比较两个对象的id属性是否一样,
// 就可以得出这两个对象是否相等
return id.equals(c.id);
}
}
在这个类“Citizen”中,覆盖了父类(Object)中的equals(),使得它能够根据对象的id属性是否相等来判断这两个对象是否相等。
然后,我们来编写一个类来测试它,如下:
public class TestCitizen {
public static void main(String[] args) {
Citizen p1 = new Citizen("id00001");
Citizen p2 = new Citizen("id00001");
System.out.println(p1.equals(p2));
}
}
这个类中,定义了一个main()方法,它是一个应用程序。在main()方法中,使用身份证号“id00001”创建了两个Citizen对象,然后,用覆盖的equals()方法比较这两个对象的相等性,此时,因为它们的身份证号相同,equals()方法因此将返回true。编译并运行这个程序,将向控制台输出如下信息:
true
我们可以试着将覆盖的equals()方法删除或注释掉,然后重新编译运行TestCitizen.java,看看运行的结构。
在这个覆盖的equals()方法中,还使用到了另一个方法getClass(),它将返回对应的对象的运行期类(runtime class)。
另外,如果一个类的父类不是Object,那么,你首先需要检查它的父类是否定义了equals()方法,如果是的话,在覆盖父类的equals()方法的时候,需要记得在子类的equals()方法中使用下面的方法来调用父类的equals()方法,以确保父类中的相关比较能够得到执行:
super.equals(obj)
例如,假设有一个类“Armyman”用来表示军人,它是一个“Citizen”的子类,此时,如果在Armyman中覆盖Citizen的equals()方法,则需要在覆盖的equals()方法中调用被覆盖的Citizen类中的equals()方法:
public boolean equals(Object obj){
return super.equals(obj)&&(其他比较语句);
}
分享到:
相关推荐
if(sf.equals("9")||sf.equals("8")||sf.equals("7")||sf.equals("6")||sf.equals("5")||sf.equals("4")||sf.equals("3")||sf.equals("2")||sf.equals("1")||sf.equals("0")||sf.equals("C")||sf.equals("←")||...
private String originAddress = "http://100.68.105.216:8080/MyTest/StudentloginServlet";//真机连接 //用于处理消息的Handler @Override protected void onCreate(Bundle savedInstanceState) { super....
Java面试题07.==和equals的区别 Java面试题08.String Java面试题09.讲一下java中的集合 Java面试题10.ArrayList 和LinkedList的区别 Java面试题11.HashMap和HashTable的区别 Java面试题12.实现一个拷贝文件的工具类...
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 ...
protected : 保护成员,该类内部和继承类中可以访问。 public : 公共成员,完全公开,没有访问限制。 internal: 在同一命名空间内可以访问。 2 .列举ASP.NET 页面之间传递值的几种方式。 答. 1.使用QueryString,...
│ Java面试题07.==和equals的区别.mp4 │ Java面试题08.String.mp4 │ Java面试题09.讲一下java中的集合.mp4 │ Java面试题10.ArrayList LinkedList.mp4 │ Java面试题11.HashMap和HashTable的区别.mp4 │ Java面试...
2. == 和 equals 的区别:==比较的是两个对象的引用是否相同,而equals()方法在默认情况下也是比较对象引用,但可以被重写来比较对象内容。 3. final在Java中的作用:final用于声明常量、防止变量被重新赋值、确保...
调通sina33下的AP6212A0版本的BT 大文实验室/大文哥 壹捌陆捌零陆捌捌陆捌贰 ...完成时间:2017/6/26 11:01 版本:V1.0 本文参照: 《A33 wifi移植说明书.pdf》 还有就是全志R16的parrotv1.1的官方SDK(Android...
//金额里面的角和分 private static final String[] jf={ "角","分" }; /** * 处理金额的整数部分,返回"...圆整" * @param integer * @return String * @throws Exception */ public static ...
2. **==和equals的区别**:`==`比较的是变量引用是否相同,而`equals()`方法比较的是对象内容是否相等。 3. **hashCode()和equals()的关系**:如果两个对象的`hashCode()`相同,但并不意味着`equals()`一定为true,...
68. session通过会话ID(session ID)跟踪用户,当用户发送请求时,服务器根据session ID找到对应的session对象。 69. 如果禁用cookie,session可以通过URL重写或HTTP头传递session ID。 70. Spring MVC和Struts都...
调通sina33下的AP6212A0(WIFI+BT) 大文实验室/大文哥 壹捌陆捌零陆捌捌陆捌贰 ...完成时间:2017/6/26 11:01 版本:V1.1 本文参照: 《A33 wifi移植说明书.pdf》 还有就是全志R16的parrotv1.1的官方SDK(Android...
== 和 equals 的区别是什么?** - **==**: 用于比较基本数据类型的值或引用数据类型的内存地址。 - 对于基本数据类型:直接比较值是否相等。 - 对于引用数据类型:比较的是对象在内存中的地址是否相同(即是否...
5. Java字符串:`String`对象是不可变的,`str1.equals(str2)`用于比较字符串内容,而`str1==str2`比较的是对象引用。 6. 系统关闭:直接断电可能损害软件数据,甚至硬件,因此应正常关机。 7. Java编程:给定的...
2. **==和equals的区别**:==是比较运算符,用于比较两个对象的引用是否指向同一个对象。equals()是Object类中的方法,用于比较两个对象的内容是否相等。equals()在不同的类中可以被重写以实现特定内容的比较。 3. ...
11、"=="和equals方法究竟有什么区别? 12、静态变量和实例变量的区别? 13、是否可以从一个static方法内部发出对非static方法的调用? 14、Integer与int的区别 15、Math.round(11.5)等於多少? Math.round(-11.5)等...
5. **Equals()和HashCode()作用**:equals用于比较两个对象的内容是否相等,hashCode是对象的哈希码,用于快速查找。 6. **Sleep()和Wait()区别**:sleep是Thread类的方法,不释放锁;wait是Object类的方法,执行时...