samedi 8 décembre 2018

Using a generic type of any nested subclass within it's abstract superclass

Suppose you have the following abstract java class:

public abstract class AbstractRequestHandler<I,O> {
    I input;
    O output;
}

and the following child classes hierarchy:

public abstract class AbstractUserRequestHandler<I extends User,O> extends AbstractRequestHandler<I,O>{...}
public abstract class AbstractUniversityRequestHandler<I extends UniversityUser> extends AbstractRequestHandler<I,String>{...}
public class AbstractStudentRequestHandler extends AbstractUniversityRequestHandler<Student>{...}
public class AbstractTeacherRequestHandler extends AbstractUniversityRequestHandler<Teacher>{...}

Suppose you need to use at a given point on the super class the generic type, for example in order to deserialize on the constructor the request json to the specific request object using gson library as follow:

public AbstractRequestHandler(final String inputJson) {
        input = new Gson().fromJson(inputJson,typeOfI);
}

You need the type of generic I within variable "typeOfI"

Is there a global solution that allows to get the generic type respecting the following constraints?

  1. The type is get at runtime regardless the child classes hierarchy ( that can be also more complex the one given as example on this question )
  2. The developer just needs to define the generic extending the super class without manually specify the generic type somewhere on concrete child class

I found the following solutions but they don't respect both the asked solution constraints.

Solution that break constraint n°2

A solution could be to define an abstract method on the superclass as follow

protected abstract Type getRequestType();

and then implement it on every concrete child class that define the generic:

public class AbstractStudentRequestHandler extends AbstractUniversityRequestHandler<Student>{

    public AbstractStudentRequestHandler(String inputJson) {
        super(inputJson);
    }

    @Override
    protected Type getRequestType() {
        return Student.class;
    }
}

Then the getRequestType() method can be used on constructor on superclass:

public AbstractRequestHandler(final String inputJson) {
        request = new Gson().fromJson(inputJson,getRequestType());
}

But even if it works regardless the child classes hierarchy ( respect constraint n°1 ) the developer should manually implement an abstract method on each concrete child class.

Solution that break constraint n°1

If the hierarchy is simple having only a direct child that extend from the superclass class, as for example:

public class AbstractTeacherRequestHandler extends AbstractRequestHandler<Teacher,String>{...}

a working solution is discussed on the following stackoverflow thread: Using a generic type of a subclass within it's abstract superclass?

However this doesn't work if the concrete class is not a direct child of the superclass with generics.





Aucun commentaire:

Enregistrer un commentaire