Question 1:
Suggest I have a example like this:
public <T> void methodA(T req) { // doSth }
psvm(){
ClassA aClass = new ClassA();
aClass.<String>methodA("hello world");
}
then can I get type String
in methodA
without actually passing String
to it?
Question 2:
If the previous example is transformed to this:
public <T> void methodA(Predicate<T> req) { // doSth }
psvm(){
ClassA aClass = new ClassA();
aClass.<String>methodA(item -> "hello world".equals(item));
}
I mean what was passed into methodA
is no more a simple object but a lambda expression, also, can I get type String
in methodA
?
CodePudding user response:
No, it is not possible to determine the generic type of a generic method, due to type erasure. At compile time, the generic type of the method is discarded, and there is no way to get this information at runtime.
public class ClassA {
public <T> void methodA(T req) {
Class<T> genericType = ?; // Impossible to get e.g. Class<String>
// [...]
}
public static void main(){
new ClassA().methodA("hello world");
}
}
There are certain scenarios where generic type information is retained (such as extending a generic class with a specific generic type, e.g. class MyList implements List<String>
). However, there is no way to do so for a generic method.
The best you could do, if you needed that information, would be to pass it in (which you stated you didn't want to do):
public <T> void methodA(T req, Class<T> type) {
// [...]
}
Another option, if all you needed was the type of the object passed in as opposed to the type of the generic method, would be to get the class of the object.
public <T> void methodA(T req) {
Class<T> type = req.getClass(); // Assuming req is non-null
// [...]
}