How can I get a list of all the implementations of an interface programmatically in Java?

Viewed 83059

Can I do it with reflection or something like that?

11 Answers

In general, it's expensive to do this. To use reflection, the class has to be loaded. If you want to load every class available on the classpath, that will take time and memory, and isn't recommended.

If you want to avoid this, you'd need to implement your own class file parser that operated more efficiently, instead of reflection. A byte code engineering library may help with this approach.

The Service Provider mechanism is the conventional means to enumerate implementations of a pluggable service, and has become more established with the introduction of Project Jigsaw (modules) in Java 9. Use the ServiceLoader in Java 6, or implement your own in earlier versions. I provided an example in another answer.

What erickson said, but if you still want to do it then take a look at Reflections. From their page:

Using Reflections you can query your metadata for:

  • get all subtypes of some type
  • get all types annotated with some annotation
  • get all types annotated with some annotation, including annotation parameters matching
  • get all methods annotated with some

The most robust mechanism for listing all classes that implement a given interface is currently ClassGraph, because it handles the widest possible array of classpath specification mechanisms, including the new JPMS module system. (I am the author.)

try (ScanResult scanResult = new ClassGraph().whitelistPackages("x.y.z")
        .enableClassInfo().scan()) {
    for (ClassInfo ci : scanResult.getClassesImplementing("x.y.z.SomeInterface")) {
        foundImplementingClass(ci);  // Do something with the ClassInfo object
    }
}

With ClassGraph it's pretty simple:

Groovy code to find implementations of my.package.MyInterface:

@Grab('io.github.classgraph:classgraph:4.6.18')
import io.github.classgraph.*
new ClassGraph().enableClassInfo().scan().withCloseable { scanResult ->
    scanResult.getClassesImplementing('my.package.MyInterface').findAll{!it.abstract}*.name
}

What erikson said is best. Here's a related question and answer thread - http://www.velocityreviews.com/forums/t137693-find-all-implementing-classes-in-classpath.html

The Apache BCEL library allows you to read classes without loading them. I believe it will be faster because you should be able to skip the verification step. The other problem with loading all classes using the classloader is that you will suffer a huge memory impact as well as inadvertently run any static code blocks which you probably do not want to do.

The Apache BCEL library link - http://jakarta.apache.org/bcel/

A new version of @kaybee99's answer, but now returning what the user asks: the implementations...

Spring has a pretty simple way to acheive this:

public interface ITask {
    void doStuff();
    default ITask getImplementation() {
       return this;
    }

}

@Component
public class MyTask implements ITask {
   public void doStuff(){}
}

Then you can autowire a list of type ITask and Spring will populate it with all implementations:

@Service
public class TaskService {

    @Autowired(required = false)
    private List<ITask> tasks;

    if ( tasks != null)
    for (ITask<?> taskImpl: tasks) {
        taskImpl.doStuff();
    }   
}

Also, if you are writing an IDE plugin (where what you are trying to do is relatively common), then the IDE typically offers you more efficient ways to access the class hierarchy of the current state of the user code.

Related