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

287 Views Asked by At

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.

1

There are 1 best solutions below

0
On BEST ANSWER

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.