Question

I have an abstract class called "ExerciseMovement" in java implementing Runnable and have concrete classes extending the abstract class implementing the run() method. In my client code, I'm trying to create a code that creates objects of all the classes that extend the abstract class and start their threads. I'm not sure if I can do that without actually knowing what classes extend the abstract class. Is it possible?

Was it helpful?

Solution 2

I don't think Java has a mecanism for that. What you could do is "register" each implementing class on a ExerciseMovementRegister which could give you a list of the classes. This would need to be done in a static block (which is not ideal). Creating objects for them is then trivial (pseudo-code, not compiled!):

List<Class<? extends ExerciseMovement>> exerciseClasses = ExerciseMovementRegister.getClasses();

for(Class klass: exerciseClasses) {
  ExerciseMovement move = (ExerciseMovement) klass.newInstance();
  move.start();
}

OTHER TIPS

Knowing all subclasses is not directly possible in java.

There are two ad-hoc solutions to this problem.

  1. Scanning entire classpath:
    For this purpose, you can use Reflections library.

    Reflections reflections = new Reflections("my.package.prefix");
    
    Set<Class<? extends ExerciseMovement>> subclasses = reflections
                      .getSubTypesOf(my.package.prefix.ExerciseMovement.class);
    

    You'd get what you want in 2 lines.
    Now creating objects and starting threads is easy.

  2. Have each class register itself (in static block) to the base class (ExerciseMovement) and maintain a list of all subclasses.

    Although it is easy to do, it won't work for all subclasses. Only subclasses which have already been loaded by classloader will be available to you.

Hope this helps.

You can't get all classes which extend a superclass with standard reflection. But you can solve this in an object oriented way:

public abstract class ExerciseMovement 
{
@SuppressWarnings("rawtypes")
private static ArrayList<Class> inheritedClasses = new ArrayList<Class>();

public ExerciseMovement()
{
    inheritedClasses.add(this.getClass());
}

@SuppressWarnings("rawtypes")
public Object[] createInheritedObjects()
{
    ArrayList<Object> result = new ArrayList<Object>();

    if(inheritedClasses.size() > 1)
    {
        for(int i = 0; i < inheritedClasses.size(); i++)
        {
            Class c = inheritedClasses.get(i);
            try 
            {
                result.add(c.newInstance());
            } 
            catch (InstantiationException e) 
            {
                e.printStackTrace();
            } 
            catch (IllegalAccessException e) 
            {
                e.printStackTrace();
            }
        }
    }

    return result.toArray();
}

}

This is definitely not a good solution, but it's the only one possible with native java

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top