在Java中,想象一下这些接口和类:
public interface Iface<S, T> { ... }
public class Parent<A, B> implements Iface<B, A> { ... }
public class Sub extends Parent<String, Integer> { ... }
是否有办法创建一个接受Iface
的函数并获取其泛型的类型。例如,如果您输入Sub.class
:
public void showTypes(Class<Iface<S, T>> ifaceClass) {
// do something...
}
//showTypes(Sub.class) --> S = Integer.class, T = String.class
编辑:关于类型擦除。如果您有ArrayList<?>
,则无法知道它是哪种通用类型。但这种情况不同。如果我有一个扩展ArrayList<String>
的类,我可以知道它的泛型类型(String.class)。请看这个片段:
@SuppressWarnings("serial")
public class StringList extends ArrayList<String> {
public static void main(String... args) {
ParameterizedType superType =
(ParameterizedType) StringList.class.getGenericSuperclass();
Type[] types = superType.getActualTypeArguments();
Class<?> clss = (Class<?>) types[0];
System.out.println(clss);
}
}
答案 0 :(得分:2)
好吧,我找到了我想要的东西。 TypeTools是一个只有一个类的小型库,旨在实现这一目标。可惜的是,它不在Maven中央存储库中。
TypeResolver.resolveArguments(Sub.class, Iface.class) --> [java.lang.Integer, java.lang.String]
Spring在GenericTypeResolver中有类似的方法:
GenericTypeResolver.resolveTypeArguments(Sub.class, Iface.class);
答案 1 :(得分:0)
不,由于在Java中实现泛型的方式,这是不可能的。在运行期间,没有关于用于泛型参数的实际类型的信息。
您可以阅读有关type erasure here
的更多详情答案 2 :(得分:-1)
Update 01.23:
我们和其他响应者回答了一个松散的具体问题,所以我们不应该得到-1票......不太公平......
Original answer:
不,没有办法......
在泛型主要规范中,当您使用T和S时,它将生成以下代码:
public void showTypes(Class<Iface<Object, Object>> ifaceClass) {
// do something...
}
所以你不会知道这些信息...
您可以使用解决方案来定义泛型类的类:
public void showTypes(T type)
{
if (s instanceof Number)
System.out.println("Number")
if (s instanceof String)
System.out.println("String")
}
但是,在我看来,这不是一个选择......
它只会在运行时确定,而不是编译时间......