在java中,使用==运算符比较Class <t>对象是个好主意吗?</t>

时间:2013-02-11 16:46:20

标签: java reflection

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

5 个答案:

答案 0 :(得分:4)

Class不会覆盖equals,因此无关紧要。如果你在课堂上调用equals,默认实现只会进行参考比较。以下是Object的默认实施,即Class.equals调用的实施:

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

话虽这么说,你唯一一次有同一个班级的两个Class个实例,当他们分享他们的名字但是在代码的两个不同的地方加载时,他们不是必要的。如果您有多个ClassLoader,则可能会发生这种情况,但这些类不一定相同,因为它们可能具有不同的字节代码。如果你可以提供帮助,我还建议避免使用多个ClassLoader方案,因为这会导致类解决方案不必要的复杂性,而且有些库不支持它。只有在应用程序启动后必须动态加载类的代码才能执行此操作,例如JNLP客户端,基于插件的应用程序等。

答案 1 :(得分:2)

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

如果在Class的情况下,永远不会有多个具有给定值的实例,则该类的equals的正确实现是引用相等。这正是Class所做的,通过继承Object equals和hashCode方法。

答案 2 :(得分:1)

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

答案 3 :(得分:0)

一般情况下,请使用equals()

在Java中,equals大致意味着“这个对象在语义上是否等同于该对象?”。另一方面,==运算符表示“此对象对象相同的对象吗?”有关详细信息,请参阅here

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

答案 4 :(得分:-4)

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

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

Object ob1 = new Object(); Object ob2 = new 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;
    }

}

现在你创建两个Vehicle实例,并调用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。

现在我们将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方法时,将调用overiden equals()。它比较两个Vehicle实例中的modelNo并相应地返回布尔值。

注意:如果覆盖equals(),那么也可以通过最佳实践来覆盖hashcode()。