通过泛型和反射避免强制类型转换:

下面这个代码是没问题的。

  1. Class clazz=Class.forName("java.util.Date");
  2. Date date= (Date) clazz.newInstance();

但是这样也没问题,编译器不会报错,但是run肯定会报错。

  1. String string= (String) clazz.newInstance();

结合泛型反射可以避免强制类型转换,让编译器帮我们检查:

  1. @SuppressWarnings(value = "unchecked")
  2. public class MainTest {
  3. public static void main(String args[]) throws Exception {
  4. Class<Date> clazz= (Class<Date>) Class.forName("java.util.Date");
  5. Date date=AFactory.getInstance(clazz);
  6. String string=AFactory.getInstance(clazz);
  7. }
  8. }
  9. class AFactory{
  10. public static<T> T getInstance(Class<T> clazz){
  11. try {
  12. return clazz.newInstance();
  13. }catch (Exception e){
  14. e.printStackTrace();
  15. System.out.println("wrong");
  16. return null;
  17. }
  18. }
  19. }

通过反射查看泛型信息 - 图1
编译器不允许编译通过。

通过反射查看泛型信息。

获取普通的成员变量的信息:

  1. public class MainTest {
  2. public static void main(String args[]) throws Exception {
  3. Class<Person> clazz=Person.class;
  4. Field field=clazz.getDeclaredField("name");
  5. Class<?> a=field.getType();
  6. System.out.println(a);
  7. }
  8. }
  9. class Person{
  10. private String name;
  11. }

打印:class java.lang.String
按上述方法获取泛型信息:

  1. public class MainTest {
  2. public static void main(String args[]) throws Exception {
  3. Class<Person> clazz=Person.class;
  4. Field field=clazz.getDeclaredField("map");
  5. Class<?> a=field.getType();
  6. System.out.println(a);
  7. }
  8. }
  9. class Person{
  10. private Map<String,Integer> map;
  11. }

打印:java.util.Map,获取不到泛型String和Interger的信息。

可以如下:

  1. public class MainTest {
  2. public static void main(String args[]) throws Exception {
  3. Class<Person> clazz=Person.class;
  4. Field field=clazz.getDeclaredField("map");
  5. Type type=field.getGenericType();
  6. System.out.println(type.getTypeName());
  7. if (type instanceof ParameterizedType){
  8. ParameterizedType parameterizedType= (ParameterizedType) type;
  9. Type rType=parameterizedType.getRawType();
  10. System.out.println("原始类型:"+rType);
  11. Type[] tArgs=parameterizedType.getActualTypeArguments();
  12. for (int i =0;i<tArgs.length;i++){
  13. System.out.println("第"+i+"个泛型类型是"+tArgs[i]);
  14. }
  15. }else {
  16. System.out.println("获取泛型类型出错");
  17. }
  18. }
  19. }
  20. class Person{
  21. private Map<Integer,String> map;
  22. }

打印:

  1. java.util.Map<java.lang.Integer, java.lang.String>
  2. 原始类型:interface java.util.Map
  3. 0个泛型类型是class java.lang.Integer
  4. 1个泛型类型是class java.lang.String