廖雪峰Java4反射与泛型-3泛型-7泛型和反射

1.部分反射API是泛型

1.1获取反射API的泛型

部分反射API是泛型,如Class<T>是泛型
       //如果使用Class,不带泛型,出现compile warning编译警告
        Class clazz1 = String.class;
       String str1 = (String) clazz1.newInstance();
        //改写为带泛型的Class,如Class<T>是泛型,
       Class<String> clazz2 = String.class;
       String str2 = clazz2.newInstance();//不用转型,直接得到
        Class<? super String> sup = clazz2.getSuperclass();

1.2获取Constructor的泛型

Constructor<T>是泛型
        Class<Integer> clazz = Integer.class;
        Constructor<Integer> cons = clazz.getConstructor(int.class);
        Integer i = cons.newInstance(123);

2.泛型数组

可以声明带泛型的数组,但不能用new创建带泛型的数组:

        Pair<String>[] ps1 = null;//声明带泛型的数组
        Pair<String>[] ps2 = new Pair<String>[2];//用new创建带泛型的数组,报错

必须通过强制转型实现带泛型的数组:

        @SuppressWarnings("unchecked")
        Pair<String>[] ps3 = (Pair<String>[]) new Pair[2];

使用泛型数组要特别小心

2.1不安全的使用泛型数组

public class Main {
    public static void main(String[] args) {
        Pair[] arr = new Pair[2];
        Pair<String>[] ps = (Pair<String>[]) arr;//arr和ps是同一个对象

        ps[0] = new Pair<String>("a","b");//指定ps[0]
        arr[1] = new Pair<Integer>(1,2);//指定ps[1]
        /**
         * Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
         * 	at com.testArray.Main.main(Main.java:15)
         */
        Pair<String> p = ps[1];
        String s = p.getFirst();//ps[1]是Integer类型,报错
    }
}

2.2安全的使用泛型数组

public class Main {
    public static void main(String[] args) {
        //扔掉arr的引用,就只能针对ps进行操作,这种引用就是安全的
        @SuppressWarnings("unchecked")
        Pair<String>[] ps = (Pair<String>[]) new Pair[2];

        ps[0] = new Pair<String>("a","b");
        Pair<String> p = ps[1];
        String s = p.getFirst();
    }
}

2.3带泛型的数组实际上是编译器的类型擦除

public class Main {
    public static void main(String[] args) {
        Pair[] arr = new Pair[2];
        Pair<String>[] ps = (Pair<String>[]) arr;

        ps[0] = new Pair<String>("a","b");//指定ps[0]
        System.out.println(ps.getClass() == arr.getClass());
        String s1 = (String) arr[0].getFirst();
        String s2 = ps[0].getFirst();
        System.out.println(s1);
        System.out.println(s2);
    }
}
### 2.4不能直接创建T[]数组 ```#java //不能直接创建T类型的数组,因为擦拭后代码变为new Object的数组,即new Object[5] class Abc{ T[] createArray(){ return new T[5]; } } ``` ```#log 方法一:必须借助Class ``` ```#java class Abc{ T[] createArray(Class cls){ return (T[]) Array.newInstance(cls,5); } } ``` ```#log 方法二:利用可变参数创建T[]数组 ``` ```#java public class ArrayHepler { @SafeVarargs static T[] asArray(T... objs){ return objs; } public static void main(String[] args){ String[] ss = asArray("a","b","c"); Integer[] ii = asArray(1,2,3); } } ``` ## 3.实例 ```#java import java.lang.reflect.Constructor; import java.util.Arrays;

public class Main {
public static void main(String[] args) throws Exception{
//创建一个泛型对象,通过其创建String对象
Class clazz = String.class;
String s1 = clazz.newInstance();
System.out.println(s1);

    //创建一个范型的Constructor对象,通过其创建String对象
    Constructor<String> cons = clazz.getConstructor(String.class);
    String s2 = cons.newInstance("Hello");
    System.out.println(s2);

    //创建一个泛型数组
    Pair<String>[] ps = (Pair<String>[]) new Pair[2];//先创建Pair数组再转型
    ps[0] = new Pair<>("a","b");
    ps[1] = new Pair<>("x","y");
    System.out.println(Arrays.toString(ps));
}

}

<img src="https://img2018.cnblogs.com/blog/1418970/201903/1418970-20190305215015922-1467877953.png" width="500" />

##    4.总结:
*    部分反射API是范型:
```#log
        Class<T> 
        Constructor<T>
  • 可以声明带泛型的数组,但不能直接创建带泛型的数组,必须强制转型
  • 可以通过Array.newInstance(Class, int)创建T[] 数组,需要强制转型
posted on 2019-02-24 15:50  singleSpace  阅读(292)  评论(0编辑  收藏  举报