在代码中使用范型可以避免对象转型,降低了异常的出现。
范型仅仅是在编译期间起作用,在运行时范型信息会被擦除,所以可以利用反射跳过范型检查
public class SkipGenerics {
public static void main(String[] args) throws Exception{
List<String> list = new ArrayList<String>();
list.add("aaa");
list.add("ccc");
Class clazz = list.getClass();
Method method = clazz.getMethod("add", Object.class);
method.invoke(list,123);
for (Object s : list) {
System.out.println(s);
}
}
}
如上所示,我们向List<String>中插入了int数字123,可以编译运行,跳过了范型检查,同时证实了范型发挥作用的时段仅仅在编译期。
对于范型中经常用到的T和?,区别理解不够透彻,只能看到部分在使用上的不同点:
ArrayList<?> arr1;
arr1 = new ArrayList<String>();
arr1 = new ArrayList<Integer>();
//以下代码编译报错
ArrayList<Object> arr2;
arr2 = new ArrayList<String>();
arr2 = new ArrayList<Integer>();
范型在实际中的使用:
public static <T,S> T copy(S s,Class<T> tClass){
try{
T t = tClass.newInstance();
BeanUtils.copyProperties(s,t);
return t;
}catch (Exception e){
logger.error("实例化异常",e);
}
return null;
}
public static <T,S> List<T> copyList(List<S> list,Class<T> tClass){
List<T> list1 = new ArrayList<T>();
try {
for (S s : list) {
T t = tClass.newInstance();
BeanUtils.copyProperties(s,t);
list1.add(t);
}
}catch (Exception e){
}
return list1;
}
以上2个方法copy和copyList都使用到了范型,降低了代码的冗余和耦合性。