Using a generic type of any nested subclass within its 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 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?
- 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 )
- 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
add a comment |
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?
- 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 )
- 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
add a comment |
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?
- 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 )
- 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
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?
- 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 )
- 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
java generics reflection
edited Dec 28 '18 at 2:37
newacct
94k23132194
94k23132194
asked Dec 8 '18 at 19:14
gcallea
3317
3317
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
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];
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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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];
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
add a comment |
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];
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
add a comment |
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];
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];
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
add a comment |
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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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