如何获取在 Java 中的方法上定义的泛型类型?
How to get a generic type which is defined on method in Java?
问题 1:
建议我举个这样的例子:
public <T> void methodA(T req) { // doSth }
psvm(){
ClassA aClass = new ClassA();
aClass.<String>methodA("hello world");
}
那么我可以在 methodA
中获取类型 String
而无需实际将 String
传递给它吗?
问题 2:
如果把前面的例子改成这样:
public <T> void methodA(Predicate<T> req) { // doSth }
psvm(){
ClassA aClass = new ClassA();
aClass.<String>methodA(item -> "hello world".equals(item));
}
我的意思是传递给 methodA
的不再是一个简单的对象,而是一个 lambda 表达式,另外,我可以在 methodA
中输入 String
吗?
不,由于类型擦除,无法确定泛型方法的泛型类型。在编译时,方法的泛型类型被丢弃,在运行时没有办法得到这些信息。
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");
}
}
在某些情况下会保留泛型类型信息(例如使用特定泛型类型扩展泛型 class,例如 class MyList implements List<String>
)。但是,对于通用方法,没有办法这样做。
如果您需要该信息,您能做的最好的事情就是将其传递(您声明您不想这样做):
public <T> void methodA(T req, Class<T> type) {
// [...]
}
如果您只需要传入对象的类型而不是泛型方法的类型,另一种选择是获取对象的 class。
public <T> void methodA(T req) {
Class<?> type = req.getClass(); // Assuming req is non-null
// [...]
}
请注意,在此特定示例中使用此选项后,泛型类型将不再用于任何用途,因此可以将其从方法签名中删除。情况可能并非总是如此,例如如果多个参数或一个参数和 return 类型需要匹配泛型类型。
public void methodA(Object req)
问题 1:
建议我举个这样的例子:
public <T> void methodA(T req) { // doSth }
psvm(){
ClassA aClass = new ClassA();
aClass.<String>methodA("hello world");
}
那么我可以在 methodA
中获取类型 String
而无需实际将 String
传递给它吗?
问题 2:
如果把前面的例子改成这样:
public <T> void methodA(Predicate<T> req) { // doSth }
psvm(){
ClassA aClass = new ClassA();
aClass.<String>methodA(item -> "hello world".equals(item));
}
我的意思是传递给 methodA
的不再是一个简单的对象,而是一个 lambda 表达式,另外,我可以在 methodA
中输入 String
吗?
不,由于类型擦除,无法确定泛型方法的泛型类型。在编译时,方法的泛型类型被丢弃,在运行时没有办法得到这些信息。
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");
}
}
在某些情况下会保留泛型类型信息(例如使用特定泛型类型扩展泛型 class,例如 class MyList implements List<String>
)。但是,对于通用方法,没有办法这样做。
如果您需要该信息,您能做的最好的事情就是将其传递(您声明您不想这样做):
public <T> void methodA(T req, Class<T> type) {
// [...]
}
如果您只需要传入对象的类型而不是泛型方法的类型,另一种选择是获取对象的 class。
public <T> void methodA(T req) {
Class<?> type = req.getClass(); // Assuming req is non-null
// [...]
}
请注意,在此特定示例中使用此选项后,泛型类型将不再用于任何用途,因此可以将其从方法签名中删除。情况可能并非总是如此,例如如果多个参数或一个参数和 return 类型需要匹配泛型类型。
public void methodA(Object req)