Determine if a Class implements a interface in Java

JavaReflection

Java Problem Overview


I have a Class object. I want to determine if the type that the Class object represents implements a specific interface. I was wondering how this could be achieved?

I have the following code. Basically what it does is gets an array of all the classes in a specified package. I then want to go through the array and add the Class objects that implement an interface to my map. Problem is the isInstance() takes an object as a parameter. I can't instantiate an interface. So I am kind of at a loss with this. Any ideas?

Class[] classes = ClassUtils.getClasses(handlersPackage);
for(Class clazz : classes)
{
    if(clazz.isInstance(/*Some object*/)) //Need something in this if statement
    {
        retVal.put(clazz.getSimpleName(), clazz);
    }
}

Java Solutions


Solution 1 - Java

You should use isAssignableFrom:

if (YourInterface.class.isAssignableFrom(clazz)) {
    ...
}

Solution 2 - Java

you can use the below function to get all the implemented interfaces

Class[] intfs = clazz.getInterfaces();

Solution 3 - Java

You can use class.getInterfaces() and then check to see if the interface class is in there.

Class someInterface; // the interface you want to check for 
Class x; // 
Class[] interfaces = x.getInterfaces();

for (Class i : interfaces) {
    if (i.toString().equals(someInterface.toString()) {
        // if this is true, the class implements the interface you're looking for
    }
}

Solution 4 - Java

You can also set the instance adding ".class"

Class[] classes = ClassUtils.getClasses(handlersPackage);
for(Class clazz : classes)
{
    if(Interface.class.isAssignableFrom(clazz))
    {
        retVal.put(clazz.getSimpleName(), clazz);
    }
}

Solution 5 - Java

A contribution for all the other answers, when possible do not use the most updated answer of method isAssignableFrom, even the "not great" answer of using clazz.getInterfaces() has better performance than isAssignableFrom.

A common mistake for developers when looking for an answer to the OP question, is to prefer isAssignableFrom when an instance is available, wrongly doing this:

if (IMyInterface.isAssignableFrom(myObject.getClass())) {
    ...

When possible, use IMyInterface.class.isInstance or instanceof as both of those have way better performance. Of course, as the OP stated; they have the drawback that you must have an instance and not just the class.

if (IMyInterface.class.isInstance(myObject)) {
    ...
if (myObject instanceof IMyInterface) { // +0.2% slower than `isInstance` (*see benchmark)
    ...

An even faster, but ugly solution would be to store an static Set with all the "valid" classes instead of checking them, this ugly solution is only preferred when you need to test classes a lot, as its performance outperforms all the other approaches for direct class check.

public static final Set<Class<?>> UGLY_SET = Stream.of(MyClass1.class, MyClass2.class, MyClass3.class).collect(Collectors.toCollection(HashSet::new));
if (UGLY_SET.contains(MyClass)) {
    ...

(*) JMH Benchmark for +0.2%

Please visit this answer from users @JBE, @Yura and @aleksandr-dubinsky, credits for them. Also, there's plenty of detail in that answer for the benchmark results to not be valid, so please take a look into it.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser489041View Question on Stackoverflow
Solution 1 - JavaFlavioView Answer on Stackoverflow
Solution 2 - JavaAnkurView Answer on Stackoverflow
Solution 3 - JavaRoddy of the Frozen PeasView Answer on Stackoverflow
Solution 4 - JavaManu NavarroView Answer on Stackoverflow
Solution 5 - Javaluiscla27View Answer on Stackoverflow