javareflectionabstract-classconcrete-inheritance

Create a concrete object in a abstract class by using reflect methods


Suppose I have an abstract class called Model with the following static method:

 
public abstract class Model {
    ...
    public static List<Model> all() {
       ...
    }
    ...
}

And a concrete class the extends it:

public class Person exends Model {
...
}

So, is it possible to, using a static context, Person.all() return a list of Person and not of Model?

You know, by using a Template, or reflect methods such as getClass().getClassName() and getClass().getDeclaredMethod() and etc.

I am asking that because I have seen that in a PHP library and I am creating a similar library in java.


Solution

  • You should always avoid reflection whenever possible. It’s slow, it’s hard to debug, it bypasses compile-time checking of types and signatures, and it can’t be optimized at runtime by the JIT.

    You probably want to use a Supplier instead:

    public static <M extends Model> List<M> all(Supplier<M> constructor) {
        List<M> models = new ArrayList<>();
    
        for ( /* ... */ ) {
            M model = constructor.get();
    
            // initialize model here
            // ...
    
            models.add(model);
        }
    }
    

    An invocation of the method looks like this:

    List<Person> allPersons = all(Person::new);
    

    Assuming, of course, that the Person class has a zero-argument constructor, or defines no constructor at all.