在 Java 中,<T>使用 == 运算符比较类对象是个好主意吗?



在.NET中,当比较Type对象时,我可以使用==。在Java中,可以使用相同的运算符来比较Class对象吗?还是应该始终使用equals()方法?

Class不会覆盖equals,所以这无关紧要。如果在类上调用equals,默认实现将只进行引用比较。以下是Object的默认实现,Class.equals调用它:

public boolean equals(Object obj) {
    return (this == obj);
}

也就是说,只有当它们共享名称,但被加载在代码中的两个不同位置时,才会有同一类的两个Class实例,此时,它们不一定相等。如果有多个ClassLoader,可能会发生这种情况,但这些类不一定相等,因为它们可能有不同的字节码。如果可以的话,我还建议避免使用多ClassLoader场景,因为这会导致类解析不必要的复杂性,而且有些库不支持它。只有在应用程序启动后必须动态加载类的代码才能做到这一点,例如JNLP客户端、基于插件的应用程序等。

如果逻辑问题是一个值相等的问题,那么我总是使用equals。这样做的原因是,它避免了有人阅读代码来检查==在特定情况下是否合适。

如果像Class的情况一样,具有给定值的实例永远不会超过一个,那么该类的equals的正确实现就是引用equality。这正是Class所做的,通过继承Objectequals和hashCode方法。

Class的实例是规范化的,所以是的,在Class的情况下,引用相等应该是可以的。

通常,使用equals()

在Java中,equals的大致意思是,"这个对象在语义上等同于那个对象吗?"。另一方面,==运算符的意思是"这个对象和那个对象是同一个对象吗?"有关更多详细信息,请参阅此处。

编辑:类不覆盖Object.equals()。仍然使用.equals),但在这种特殊情况下,它与==相同。

当您使用==比较两个实例时,实际上是在比较它们的内存地址,以查看它们是否是对同一对象的引用。

假设您创建了两个如下所示的对象,

Object ob1=new Object();Object ob2=新Object();

现在ob1==ob2返回false。因为ob1和ob2指的是不同的内存地址。

但如果你按照以下方式分配ob1=ob2,则(ob1==ob2)返回true。因为两者都指向相同的内存地址。

如果使用equals()比较两个对象,那么JVM将检查是否覆盖equals方法。如果不是,则调用Object的equals方法并相应地返回布尔值。

如果重写equals(),jvm将根据实现返回布尔值。

您的车辆等级如下,

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;
    }
}

现在您创建两个车辆实例,如下所示,并调用equal()

Vehicle vehicle1 = new Vehicle();
vehicle1.setModelNo(111);
Vehicle vehicle2 = new Vehicle();
vehicle2.setModelNo(111);
System.out.println(vehicle1.equals(vehicle2));

输出应该是false,因为我们不覆盖equals(),它调用Object的equals((),检查内存地址并返回false。

现在我们修改车辆类别如下,

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));

现在输出应该为true。因为我们覆盖了Vehicle类中的equals方法。因此,当我们在Vehicle的任何实例上调用equals方法时,就会调用overden equals()。它比较两个Vehicle实例中的modelNo,并相应地返回布尔值。

注意:如果您重写equals(),那么最佳实践也是重写hashcode()。

相关内容

  • 没有找到相关文章

最新更新