Using a generic type of any nested subclass within its abstract superclass












0














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 AbstractUserRequestHandler<I,String>{...}
public class StudentRequestHandler extends AbstractUniversityRequestHandler<Student>{...}
public class TeacherRequestHandler 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 specified by a concrete child class that respects the following constraints?




  1. The type is gotten 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 ( for example on overrided method or constructor )


So that if you want to define a new concrete child that assign a new value to a generic you can just write the following concrete class for example:



public class StudentRequestHandler extends AbstractUniversityRequestHandler<Student>{

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

}




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 defines the generic:



public class StudentRequestHandler extends AbstractUniversityRequestHandler<Student>{

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

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


Then the getRequestType() method can be used on constructor on the target 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 target superclass, as for example:



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


a working solution has been proposed by @naikus ( https://stackoverflow.com/users/306602/naikus ) 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 that defines the generics ( as the one proposed as example on this question ).










share|improve this question





























    0














    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 AbstractUserRequestHandler<I,String>{...}
    public class StudentRequestHandler extends AbstractUniversityRequestHandler<Student>{...}
    public class TeacherRequestHandler 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 specified by a concrete child class that respects the following constraints?




    1. The type is gotten 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 ( for example on overrided method or constructor )


    So that if you want to define a new concrete child that assign a new value to a generic you can just write the following concrete class for example:



    public class StudentRequestHandler extends AbstractUniversityRequestHandler<Student>{

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

    }




    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 defines the generic:



    public class StudentRequestHandler extends AbstractUniversityRequestHandler<Student>{

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

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


    Then the getRequestType() method can be used on constructor on the target 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 target superclass, as for example:



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


    a working solution has been proposed by @naikus ( https://stackoverflow.com/users/306602/naikus ) 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 that defines the generics ( as the one proposed as example on this question ).










    share|improve this question



























      0












      0








      0


      1





      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 AbstractUserRequestHandler<I,String>{...}
      public class StudentRequestHandler extends AbstractUniversityRequestHandler<Student>{...}
      public class TeacherRequestHandler 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 specified by a concrete child class that respects the following constraints?




      1. The type is gotten 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 ( for example on overrided method or constructor )


      So that if you want to define a new concrete child that assign a new value to a generic you can just write the following concrete class for example:



      public class StudentRequestHandler extends AbstractUniversityRequestHandler<Student>{

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

      }




      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 defines the generic:



      public class StudentRequestHandler extends AbstractUniversityRequestHandler<Student>{

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

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


      Then the getRequestType() method can be used on constructor on the target 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 target superclass, as for example:



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


      a working solution has been proposed by @naikus ( https://stackoverflow.com/users/306602/naikus ) 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 that defines the generics ( as the one proposed as example on this question ).










      share|improve this question















      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 AbstractUserRequestHandler<I,String>{...}
      public class StudentRequestHandler extends AbstractUniversityRequestHandler<Student>{...}
      public class TeacherRequestHandler 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 specified by a concrete child class that respects the following constraints?




      1. The type is gotten 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 ( for example on overrided method or constructor )


      So that if you want to define a new concrete child that assign a new value to a generic you can just write the following concrete class for example:



      public class StudentRequestHandler extends AbstractUniversityRequestHandler<Student>{

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

      }




      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 defines the generic:



      public class StudentRequestHandler extends AbstractUniversityRequestHandler<Student>{

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

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


      Then the getRequestType() method can be used on constructor on the target 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 target superclass, as for example:



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


      a working solution has been proposed by @naikus ( https://stackoverflow.com/users/306602/naikus ) 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 that defines the generics ( as the one proposed as example on this question ).







      java generics reflection






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Dec 28 '18 at 2:37









      newacct

      94k23132194




      94k23132194










      asked Dec 8 '18 at 19:14









      gcallea

      3317




      3317
























          1 Answer
          1






          active

          oldest

          votes


















          0














          You can't get generic parameter without inheritence because of generics in java has type erasure : https://docs.oracle.com/javase/tutorial/java/generics/erasure.html



          You need to do approach which you've been shared in your question. Using inheritence and ParameterizedType :



          (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];





          share|improve this answer





















          • Thanks for your answer. The inheritance is the base of my question cause I asked how to get type defined by concrete child classes on the super class ( not necessarily the direct one ). Yes,the shared question approach you mentioned works only if the concrete class that specifies the generic inherits directly from the parent class.If you have instead a hierarchy with inherited level >=2 it is not suitable cause "getGenericSuperclass()" method returns the Type representing the direct superclass of the entity.I was looking for a solution that allows to get it regardless the hierarchy structure.
            – gcallea
            Dec 10 '18 at 10:37











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53686017%2fusing-a-generic-type-of-any-nested-subclass-within-its-abstract-superclass%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          0














          You can't get generic parameter without inheritence because of generics in java has type erasure : https://docs.oracle.com/javase/tutorial/java/generics/erasure.html



          You need to do approach which you've been shared in your question. Using inheritence and ParameterizedType :



          (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];





          share|improve this answer





















          • Thanks for your answer. The inheritance is the base of my question cause I asked how to get type defined by concrete child classes on the super class ( not necessarily the direct one ). Yes,the shared question approach you mentioned works only if the concrete class that specifies the generic inherits directly from the parent class.If you have instead a hierarchy with inherited level >=2 it is not suitable cause "getGenericSuperclass()" method returns the Type representing the direct superclass of the entity.I was looking for a solution that allows to get it regardless the hierarchy structure.
            – gcallea
            Dec 10 '18 at 10:37
















          0














          You can't get generic parameter without inheritence because of generics in java has type erasure : https://docs.oracle.com/javase/tutorial/java/generics/erasure.html



          You need to do approach which you've been shared in your question. Using inheritence and ParameterizedType :



          (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];





          share|improve this answer





















          • Thanks for your answer. The inheritance is the base of my question cause I asked how to get type defined by concrete child classes on the super class ( not necessarily the direct one ). Yes,the shared question approach you mentioned works only if the concrete class that specifies the generic inherits directly from the parent class.If you have instead a hierarchy with inherited level >=2 it is not suitable cause "getGenericSuperclass()" method returns the Type representing the direct superclass of the entity.I was looking for a solution that allows to get it regardless the hierarchy structure.
            – gcallea
            Dec 10 '18 at 10:37














          0












          0








          0






          You can't get generic parameter without inheritence because of generics in java has type erasure : https://docs.oracle.com/javase/tutorial/java/generics/erasure.html



          You need to do approach which you've been shared in your question. Using inheritence and ParameterizedType :



          (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];





          share|improve this answer












          You can't get generic parameter without inheritence because of generics in java has type erasure : https://docs.oracle.com/javase/tutorial/java/generics/erasure.html



          You need to do approach which you've been shared in your question. Using inheritence and ParameterizedType :



          (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Dec 10 '18 at 6:15









          Emre Savcı

          2,0211619




          2,0211619












          • Thanks for your answer. The inheritance is the base of my question cause I asked how to get type defined by concrete child classes on the super class ( not necessarily the direct one ). Yes,the shared question approach you mentioned works only if the concrete class that specifies the generic inherits directly from the parent class.If you have instead a hierarchy with inherited level >=2 it is not suitable cause "getGenericSuperclass()" method returns the Type representing the direct superclass of the entity.I was looking for a solution that allows to get it regardless the hierarchy structure.
            – gcallea
            Dec 10 '18 at 10:37


















          • Thanks for your answer. The inheritance is the base of my question cause I asked how to get type defined by concrete child classes on the super class ( not necessarily the direct one ). Yes,the shared question approach you mentioned works only if the concrete class that specifies the generic inherits directly from the parent class.If you have instead a hierarchy with inherited level >=2 it is not suitable cause "getGenericSuperclass()" method returns the Type representing the direct superclass of the entity.I was looking for a solution that allows to get it regardless the hierarchy structure.
            – gcallea
            Dec 10 '18 at 10:37
















          Thanks for your answer. The inheritance is the base of my question cause I asked how to get type defined by concrete child classes on the super class ( not necessarily the direct one ). Yes,the shared question approach you mentioned works only if the concrete class that specifies the generic inherits directly from the parent class.If you have instead a hierarchy with inherited level >=2 it is not suitable cause "getGenericSuperclass()" method returns the Type representing the direct superclass of the entity.I was looking for a solution that allows to get it regardless the hierarchy structure.
          – gcallea
          Dec 10 '18 at 10:37




          Thanks for your answer. The inheritance is the base of my question cause I asked how to get type defined by concrete child classes on the super class ( not necessarily the direct one ). Yes,the shared question approach you mentioned works only if the concrete class that specifies the generic inherits directly from the parent class.If you have instead a hierarchy with inherited level >=2 it is not suitable cause "getGenericSuperclass()" method returns the Type representing the direct superclass of the entity.I was looking for a solution that allows to get it regardless the hierarchy structure.
          – gcallea
          Dec 10 '18 at 10:37


















          draft saved

          draft discarded




















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53686017%2fusing-a-generic-type-of-any-nested-subclass-within-its-abstract-superclass%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Mossoró

          Error while reading .h5 file using the rhdf5 package in R

          Pushsharp Apns notification error: 'InvalidToken'