我有以下功能:
public <T> void putList(String key, List<T> lst){
if (T instanceof String) {
// Do something
}
if (T instanceof Integer) {
// Do something
}
}
在这个功能中,我想知道&lt; T&gt;是字符串还是整数,所以我想知道是否有办法发现它的类型?我使用了上面的代码,但它生成了错误
提前谢谢。
答案 0 :(得分:9)
由于类型信息被删除,您无法找到T
的类型。查看this了解更多详情。但是,如果列表不为空,您可以从列表中获取一个元素,并可以使用instanceof
和if else
答案 1 :(得分:9)
由于erasure,Java无法实现。大多数人做的是添加类型令牌。例如:
public <T> void putList(String key, List<T> list, Class<T> listElementType) {
}
在某些情况下,反射可以在type参数中获得,但它适用于您已预先设置type参数的情况。例如:
public class MyList extends List<String> {
private List<String> myField;
}
在这两种情况下,反射可以确定List的类型为String,但反射无法确定您的情况。您必须使用类似令牌的其他方法。
答案 2 :(得分:1)
由于erasure,无法确定这一点,这意味着参数未存储在代码中。但是,您可以传递一个额外的参数来指定列表的类型:
public <T> void putList(String key, List<T> lst, Class<T> listElementType) {
}
或者您可以在运行时确定每个元素的类型:
public <T> void putList(String key, List<T> lst){
for (Object elem:lst) {
if (elem instanceof String) {
// Do something
}
if (elem instanceof Integer) {
// Do something
}
}
}
答案 3 :(得分:1)
泛型称为“擦除”,因为它们仅在编译时存在,并由编译器删除。因此,无法确定通用类型的集合。对非空列表执行此操作的唯一方法是获取第一个元素并确定其类型。
这几乎与DJClayworth建议的解决方案相同,但我认为没有必要检查列表中的每个元素。如果您确定列表是使用泛型(new ArrayList()或new LinkedList()等)创建的,则所有元素都保证属于同一类型。
答案 4 :(得分:0)
如果要运行对象的功能,可以执行以下操作:
Your meeting request was declined. The invitation was declined because it occurred in the past.
答案 5 :(得分:-1)
使用instanceof运算符。
也就是说,通用操作应该是通用的,因此要小心改变基于类型的行为。
答案 6 :(得分:-1)
Type genericType = lst.getType();
if(genericType instanceof ParameterizedType){
ParameterizedType aType = (ParameterizedType) genericType;
Type[] fieldArgTypes = aType.getActualTypeArguments();
for(Type fieldArgType : fieldArgTypes){
Class fieldArgClass = (Class) fieldArgType;
System.out.println("fieldArgClass = " + fieldArgClass);
}
}