0

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?

streetsoldier
  • 1,259
  • 1
  • 14
  • 32
  • Maybe something like [this](http://stackoverflow.com/questions/205573/at-runtime-find-all-classes-in-a-java-application-that-extend-a-base-class) can help you? – Stefan Apr 04 '14 at 07:30
  • That's [easy](http://code.google.com/p/reflections/). Although I would recommend you use a thread pool rather than raw `Thread`. – Boris the Spider Apr 04 '14 at 07:32

3 Answers3

1

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.

Tanmay Patil
  • 6,882
  • 2
  • 25
  • 45
0

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();
}
Martin
  • 7,634
  • 1
  • 20
  • 23
-1

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

Shadow3097
  • 28
  • 7