在 .NET 中,我可以在比较 Type 对象时摆脱 == 。可以使用相同的运算符来比较 Java 中的 Class 对象还是应该始终使用 equals() 方法?
5 回答
Class
不会覆盖equals
,所以没关系。如果你调用equals
类,默认实现只会做一个参考比较。这是来自 的默认实现Object
,它Class.equals
调用:
public boolean equals(Object obj) {
return (this == obj);
}
话虽如此,唯一一次您将拥有Class
同一个类的两个实例是当它们共享名称但在代码中的两个不同位置加载时,此时它们不一定相等。如果您有多个 ,则可能会发生这种情况ClassLoader
,但这些类不一定相等,因为它们可能具有不同的字节码。如果您可以提供帮助,我还建议避免使用多种ClassLoader
情况,因为这会导致类解析不必要的复杂性,并且某些库不支持它。只有在应用程序启动后必须动态加载类的代码才应该这样做,例如 JNLP 客户端、基于插件的应用程序等。
如果逻辑问题是价值平等之一,那么我将始终使用等于。这样做的原因是它避免了任何人需要阅读代码来检查 == 在特定情况下是否合适。
如果像 Class 的情况一样,具有给定值的实例永远不会超过一个,则该类的 equals 的正确实现是引用相等。这正是 Class 所做的,通过继承 Object 的 equals 和 hashCode 方法。
的实例Class
是规范化的,所以是的,在 . 的情况下引用相等应该没问题Class
。
一般来说,使用equals()
.
在 Java 中,equals
大致意思是“这个对象在语义上是否等同于那个对象?”。==
另一方面,运算符的意思是“这个对象和那个对象是同一个对象吗?” 有关更多详细信息,请参见此处。
编辑:类不会覆盖 Object.equals()。仍然使用 .equals(),但在这种特殊情况下它与 == 相同。
当您使用 == 比较两个实例时,您实际上是在比较它们的内存地址以查看它们是否是对同一对象的引用。
假设如果您创建两个对象,如下所示,
对象 ob1 = 新对象();对象 ob2 = 新对象();
现在 ob1 == ob2 返回 false。因为 ob1 和 ob2 指的是不同的内存地址。
但如果你指定如下 ob1 = ob2,那么 (ob1 == ob2) 返回 true。因为两者都指的是同一个内存地址。
如果您使用 equals() 比较两个对象,那么 JVM 会检查您是否覆盖了 equals 方法。如果不是,它会调用 Object 的 equals 方法并相应地返回布尔值。
如果您覆盖 equals(),则 jvm 根据实现返回布尔值。
您的 Vehicle 类如下所示,
public class Vehicle {
private int modelNo;
private String color;
/**
* @return the modelNo
*/
public int getModelNo() {
return modelNo;
}
/**
* @param modelNo
* the modelNo to set
*/
public void setModelNo(int modelNo) {
this.modelNo = modelNo;
}
}
现在您创建两个 Vehicle 实例,如下所示并调用 equal()
Vehicle vehicle1 = new Vehicle();
vehicle1.setModelNo(111);
Vehicle vehicle2 = new Vehicle();
vehicle2.setModelNo(111);
System.out.println(vehicle1.equals(vehicle2));
输出应该是假的,因为我们没有覆盖 equals() 并且它调用对象的 equals() 并且它检查内存地址并返回假。
现在我们修改 Vehicle 类如下,
public class Vehicle {
private int modelNo;
private String color;
/**
* @return the modelNo
*/
public int getModelNo() {
return modelNo;
}
/**
* @param modelNo
* the modelNo to set
*/
public void setModelNo(int modelNo) {
this.modelNo = modelNo;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((color == null) ? 0 : color.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Vehicle))
return false;
Vehicle other = (Vehicle) obj;
if (color == null) {
if (other.color != null)
return false;
} else if (!color.equals(other.color))
return false;
return true;
}
}
现在我们创建两个具有相同 modelNo 的 Vehicle 实例,并在其中一个实例上调用 equals(),如下所示,
Vehicle vehicle1 = new Vehicle();
vehicle1.setModelNo(111);
Vehicle vehicle2 = new Vehicle();
vehicle2.setModelNo(111);
System.out.println(vehicle1.equals(vehicle2));
现在输出应该是真的。因为我们重写了 Vehicle 类中的 equals 方法。因此,当我们在任何 Vehicle 实例上调用 equals 方法时,将调用覆盖的 equals()。它比较两个 Vehicle 实例中的 modelNo 并相应地返回布尔值。
注意:如果您覆盖了 equals(),那么最好的做法也是覆盖 hashcode()。