java - 为什么 java 对象比较在 '==' 和 .equals() 方法上都失败了?
问题描述
我正在使用 == 和 equals() 方法比较相同的对象,但它们都失败了。我尝试了以下四种组合。请有人指导我在哪里犯错。
public class Question {
int rollNo;
String name;
Question(int rollNo, String name) {
this.rollNo = new Integer(rollNo);
this.name = new String(name);
}
public int getRollNo() {
return new Integer(rollNo);
}
public void setRollNo(int rollNo) {
if(rollNo>0) this.rollNo = rollNo;
}
public String getName() {
return new String(name);
}
public void setName(String name) {
if(name!=null) this.name = name;
}
public static void main(String[] args) {
Question obj1 = new Question(123, "Student1");
Question obj2 = new Question(123, "Student1");
Question obj3 = new Question(456, "Student2");
// All if conditions are evaluating to false
if(obj1 == obj2) System.out.println("Equal objects 1 and 2 using ==");
if(obj1.equals(obj2)) System.out.println("Equal objects 1 and 2 using equals()");
if(obj1 == new Question(123, "Student1")) System.out.println("Equal objects 1 and 2 using == and new");
if((new Question(123, "Student1")).equals(obj2)) System.out.println("Equal objects 1 and 2 using equals() and new");
}
}
我也欢迎关于我的代码质量的建议,因为我刚刚开始编码。
解决方案
它失败了,==
因为Question
对象是不同的对象。(==
引用类型的运算符测试以查看引用是否针对同一对象。)
它失败了,equals
因为您正在使用该Object::equals(Object)
方法。该方法被指定为具有与 相同的含义==
。
如果你想Question::equals(Object)
表现得不同,你需要通过添加这样的方法来覆盖继承自的方法:Object
@Override
public boolean equals(Object other) {
// implement this according to the spec to give the equality
// semantics you need
}
实际的实现可能如下所示:
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof Question) {
Question other = (Question) obj;
return this.rollNo == other.rollNo &&
this.name.equals(other.name);
} else {
return false;
}
}
我注意到您的代码中还有其他一些问题。例如:
Question(int rollNo, String name) {
this.rollNo = new Integer(rollNo);
this.name = new String(name);
}
- 构造函数应该是
public
. - 由于
this.rollNo
被声明为 anint
,因此创建 anInteger
并分配它是毫无意义的......而且效率低下。将会发生的情况是,Integer
将拆箱以获取其值,然后该对象将被丢弃。只需分配rollNo
给this.rollNo
. - 如果您确实需要显式获取
Integer
实例,那么正确的方法是使用. 这利用了内置的对象缓存。Integer.valueOf(int)
Integer
- 创建一个字符串
new String(name)
是不必要且低效的。字符串是不可变的。不需要复制它们。当然,不是这里。
推荐阅读
- racket - 在值表达式上使用可变参数函数
- java - 如何在运行时创建与另一个相同类型的对象?
- javascript - 将文本框中的值添加到计数器
- mongodb - 您如何监控 MongoDB 数据库以在主要数据库操作期间验证其状态?
- java - 找不到任何实现 Connector 且名称与 io.streamthoughts.kafka.connect.filepulse.source.FilePulseSourceConnector 匹配的类
- python - 函数对象是 Python 中的内置类类型吗?
- android - Android Studio - 升级 gradle ':app:checkReleaseDuplicateClasses' 任务失败后
- java - 排除的嵌入式 tomcat 仍然存在于 lib-provided 文件夹中
- javascript - 如果语句在 https 获取响应中移过 [ ]
- llvm - 执行带有分段错误的 LLVM 代码结果