Java 比较类对象

Java 比较类对象,java,Java,我必须将类对象与预定义类列表进行比较 使用==安全吗?还是应该使用equals if (klass == KlassA.class) { } else if (klass == KlassB.class) { } else if (klass == KlassC.class) { } else { } 注意:我不能使用的instanceof,我没有对象,我只有类对象。在这种情况下,我(错误地)像枚举一样使用它 可能是安全的 如果对象不重写Equals方法,它将在引用之间进行比较。

我必须将
对象与预定义类列表进行比较

使用
==
安全吗?还是应该使用
equals

if        (klass == KlassA.class) {
} else if (klass == KlassB.class) {
} else if (klass == KlassC.class) {
} else {
}
注意:我不能使用
的instanceof
,我没有对象,我只有
对象。在这种情况下,我(错误地)像枚举一样使用它

可能是安全的


如果对象不重写
Equals
方法,它将在引用之间进行比较。如果两个变量指向同一个对象,则它们的引用匹配。

对于大多数Java应用程序,这是正确的。但是,仅当两个类都由相同的类加载器加载时,使用运算符==比较Java类是安全的。

Java.lang.Class
覆盖
Java.lang.Object
中的
equals
方法,该方法的实现如下:

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

因此
a==b
a.equals(b)
相同(除非
a
为空)。

我不确定这是否适用于您的特定情况,但您可以尝试


我更喜欢使用==来比较类对象和枚举常量,因为在类型不兼容的情况下,它会导致编译时错误

例如:

Class<?> cls1 = Void.class;
String cls2 = "java.lang.String";

if (cls1 == cls2) doSomething();        // Won't compile

if (cls1.equals(cls2)) doSomething();   // Will compile
Class cls1=Void.Class;
String cls2=“java.lang.String”;
如果(cls1==cls2)doSomething();//不会编译
如果(cls1.equals(cls2))doSomething();//将编译

如前面的答案所述,要比较类类型的对象(或java.lang.Class对象),我们应该使用==运算符。然而,这可能有点令人困惑,因为通过==运算符在对象之间进行比较的结果总是不能得到正确的结果(我们通常使用equal()方法)。例如,此表达式的结果为false:

new String("book") == new String("book")//false
原因是,

虚拟机为每种类型管理一个唯一的类对象。 因此,您可以使用==运算符来比较java.lang.Class 对象。从

因此:

new String("book").getClass() == new String("book").getClass()//true


结果为真。

这不重要。两个名称相同但由不同类加载器加载的类将不会具有相同的地址,也不会是同一个类。所以
==
将为false,这是正确的。如果OP想要比较不同的类名(然后使用
klass.getName().equals(xxxx.class.getName())
。或者因为类型是自反的,您也可以使用klassA.isAssignableFrom(klasB)和&klassB.isAssignableFrom(klasA)对于equality@Steiny,这听起来有点过分了,为了公平起见,我们可以比较类引用。严格来说,每个虚拟机只有一个具有给定名称的类是不正确的。因为类加载器是类对象标识的一部分,所以同时加载具有相同名称的类的几个加载器将生成两个类t不相等。首先,感谢您的评论。根据oracle文档,您的观点是正确的:“一个类由它的全名和类加载器决定”。我相信您知道,class.forName(…)返回一个与类包和名称相对应的类对象,它位于调用方或当前类加载器中。如,classLoader.loadClass(className)用于将类对象获取到特殊的类加载器。因此,在当前类加载器中,我们可以使用Class.forName(…)比较。我要说的是-您确实可以比较几个
类的结果。forName
在单个表达式中调用,但是如果您将
对象保存在某个字段中并存储它,那么它不一定总是等于以后从不同的类加载上下文调用
类.forName
的结果。这在过去是几个相当大的图书馆的问题,这就是为什么我觉得应该提到它。
new String("book").getClass() == new String("book").getClass()//true
Class.forName("java.lang.String") == Class.forName("java.lang.String")//true