AndreaF
AndreaF

Reputation: 12395

instanceof vs equals on defined string that identifies the Class

I can test the class type in a program where I'm working both with instanceof or getting a field that identifies the class appartenency. so the choice is between

if(myObjec instanceof Something){
} 

And

if(myObjec.geClassType().equals("Something")){
}

What is the best in terms of efficency?

geClassType() is a method present in the object of the program where I'm working(not a standard java method) and is a method that returns a string wih the name of the class. the name is passed as field when the object is created

EDIT the field that I get in the second sample in my code doesn't identify exactly the class but a category and is used also for different routines, but I can use this also for this purpose since I use a specific object for each category. So I have reported this as getClassType to make my question more clear.

Upvotes: 4

Views: 4919

Answers (4)

Luiggi Mendoza
Luiggi Mendoza

Reputation: 85779

You probably mean what's the difference if verifying if the object reference belongs to a specific class using instanceof vs comparing the name of the class.

instanceof works for object references that are from the class or for a subclass of the class being compared. In case of interfaces, it returns true if the class (or a super class) of the object reference implements this interface.

getClass().getName().equals("NameOfTheClass") (masked by your getClassType method) will verify if the class of the object reference is exactly from another class, thus a sub class won't pass this test.

Which one to use? Use the one that better suits for your case:

  • If you want/need to use object references that belongs to a certain class or interface, despite if the class of the object reference is a subclass or implements the interface, then use instanceof. For example, when iterating through the elements of a Collection to verify if some objects implement a desired interface.

  • If you need to determine if the class of the object reference is exactly a specific class, use getClass().getName().equals("..."). For example, when implementing equals method in a class that should compare to elements that belongs only to this class (no subclasses allowed). Some IDEs do this when auto generating equals method.

Still, a better option than getClass().getName().equals("...") would be getClass().equals(TheClass.class).


In terms of efficiency, if you need to verify if the object belongs to a specific class only, use getClass().equals(TheClass.class) rather than getClass().getName().equals("...") because one will compare references (which is as fast as instanceof). But if you only have the class name, use your current approach. Do not worry about the performance of the application because the JIT will optimize the code at runtime for you after several executions of the code. Still, f you think this statement may be a performance bottleneck, prove it using a profiler.

Upvotes: 3

Michael Berry
Michael Berry

Reputation: 72334

instanceof is more efficient, actually works (since geClassType() doesn't exist) and is much more readable.

If instanceof is the behaviour that you want (as other answers point out the behaviour is potentially different between the two methods you outline) I'm not sure why you'd even consider the alternative?

EDIT: I should reiterate, even if you have a method in your context that does do what you describe, I still can't see a good reason to do it that way. It may introduce bugs if it doesn't work exactly the way you expect all the time (such as with similarly named classes in different packages), it will likely be slower, but more importantly it's non standard so makes your code much less readable.

In short, instanceof is a useful keyword that does exactly what you want, reliably and readably, with the minimum of fuss. Why on earth wouldn't you use it?!

Upvotes: 6

ajb
ajb

Reputation: 31699

The two may or may not work differently.

if(myObjec instanceof Something){ 
}

The condition is true if myObjec's class, at runtime, is either Something or any class derived from Something, directly or indirectly.

if(myObjec.geClassType().equals("Something")){
}

If geClassType is a method in Something that returns "Something", and it is not overridden in any subclass, then this is equivalent to using instanceof. But if there are any subclasses of Something that override geClassType to return a different string, then instanceof would return true for objects of that class, while the second would return false.

If the two really are equivalent, I don't know which one would be more efficient, and it wouldn't surprise me if the answer varied from one implementation to another.

P.S. I agree with the comment that doing either one of these is probably wrong. Instead, you should consider how you could arrange the logic inside the curly braces to make it polymorphic; or if there's some property that you're trying to test for that is true of Something and false for other classes, then add a polymorphic boolean isGrungy() or boolean hasGrunginess() method to make it clear what you're trying to test for, instead of relying on the class name.

Upvotes: 0

Nivas
Nivas

Reputation: 18354

You probably meant getClass.

instanceof is better because

  • getClass uses the class name as a String which can misspelt and this will never be found out (the equality check will return false),
  • instanceOf uses the class itself
  • The second argument of instanceof is checked at compile time, not only for the class name but also for the class hierarchy (for example, "test" isnanceof Integer will get a compile time error).

Upvotes: -1

Related Questions