29

I have to compare a Class object against a list of pre-defined classes.

Is it safe to use == or should I use equals?

if        (klass == KlassA.class) {
} else if (klass == KlassB.class) {
} else if (klass == KlassC.class) {
} else {
}

Note: I cannot use instanceof, I don't have an object, I just have the Class object. I (mis)use it like an enum in this situation!

6 Answers 6

35

java.lang.Class does not override the equals method from java.lang.Object, which is implemented like this:

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

So a == b is the same as a.equals(b) (except if a is null).

Sign up to request clarification or add additional context in comments.

Comments

5

I am not sure if this will work for your specific situation, but you could try Class.isAssignableFrom(Class).

KlassA.class.isAssignableFrom(klass)

2 Comments

Or because types are reflexive you could also use klassA.isAssignableFrom(klasB) && klassB.isAssignableFrom(klasA) for equality
@Steiny, that sounds like an overkill, for equality we can just compare class references.
3

For the most of the Java applications this is correct. However, comparing Java classes using the operator == is safe just if both the classes are loaded by the same classloader.

1 Comment

That shouldn't matter. Two classes with the same name but loaded by different class loaders will not have the same address nor will they be the same class. So == would be false and that would be correct. If the OP wanted to compare class names that would be different (and then use klass.getName().equals(xxxx.class.getName()).
3

As mentioned in previous answers, to compare objects of Class type (or java.lang.Class objects) we should use == operator. However, It may be a bit confusing because always the result of comparison between objects through == operator can not cause right results (we usually use equal() method). For example, the result of this expression is false:

new String("book") == new String("book")//false

The reason is that,

The virtual machine manages a unique Class object for each type. Therefore, you can use the == operator to compare java.lang.Class objects. From Core Java for the Impatient - Page 153

Therefore:

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

or

Class.forName("java.lang.String") == Class.forName("java.lang.String")//true

result in true.

3 Comments

It's not strictly true that only one class will exist with a given name per virtual machine. Since ClassLoader is a part of Class object identity, several loaders which have concurrently loaded class with the same name will produce two classes that aren't equal.
First, thanks for your comment. Your point is correct, according oracle doc: "A class is determined by its full name and the class loader". As I am sure you know, Class.forName(...) returns a Class object corresponding to a class package and name, which is located in caller or current class loader. As, classLoader.loadClass(className) is used for getting Class object to a special class loader. So, in current class loader we can use Class.forName(...) to comparison.
what I'm saying is - you indeed can compare result of several Class.forName calls in single expression, but if you save the Class object in a field somewhere and stored it, then it won't necessarily be always equal to results of later calls to Class.forName from different classloading contexts. This was a problem for several pretty big libraries in the past, which is why I felt like it should be mentioned.
1

It's probably safe.

If the object doesn't override the Equals method it will make a comparison between the references. And if two variables point to the same object, their references match.

Comments

0

I prefer to use == for comparison between class objects and enum constants because it results in compilation time errors in case of incompatible types.

For example:

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

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

if (cls1.equals(cls2)) doSomething();   // Will compile

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.