使用等号运算符比较两个类

8
使用等号运算符比较类实例有哪些陷阱?
boolean compareTypes(Class<?> clazz, Class<?> rootClazz) {
    return clazz == rootClazz;
}
5个回答

14

没有真正的陷阱; 它的行为就像您所期望的那样,如果您期望实际行为 :) 另外,Class对象的equals()方法只是从Object继承的方法,它使用==运算符。

唯一令人惊讶的部分是,如果同一类文件被两个不同的类加载器加载,则会得到两个单独的类对象,这些对象将比较为false。 这是设计上的考虑。


当然,如果涉及到两个类加载器,返回false是完全正确的。 - Marko Topolnik
1
这正是“这是按设计要求”所意味的。 - Ernest Friedman-Hill

3
如果这些类是由不同的ClassLoader加载的,则这些类可能来自同一文件,但并非由同一对象表示。在这种情况下,它们也可能具有不同的行为,因为其中一个加载器可能已经执行了字节码修改。

1

没有陷阱。Class没有覆盖默认的Object.equals,因此语义相同,只是使用equals会有一个陷阱,因为左操作数为null将引发NPE。


@OrangeDog...它在答案中所说的内容。 - Marko Topolnik
@OrangeDog 他提到了这个陷阱,虽然不是很大的陷阱,但与使用“==”相比仍然有些不便。因此,这是一个小陷阱。 - Jon Taylor
@JonTaylor 所以这是一个小坑 :) - Marko Topolnik
@JonTaylor 在我评论时,“左操作数”还不存在。 - OrangeDog
@OrangeDog 可能你的屏幕上没有显示出来,但它确实存在。我发了一篇帖子,然后在30秒内进行了编辑。 - Marko Topolnik

0

该类没有重写equals方法,并且直接扩展了Object类,因此在这种情况下equals和==是相同的。

尽管如此,在可能的情况下最好使用equals方法。

如果您不知道==和equals方法之间的区别,请去了解一下。


-1

也许更明智的做法是

boolean compareTypes(Class<?> clazz, Class<?> rootClazz) {
    return clazz.getName().equals(rootClazz.getName());
}

或者一些类似于getName()的版本,例如getSimpleName()


1
getSimpleName 在不同包中名称相同的类中会出现问题。 - Sayo Oladeji

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接