泛型不能万能的,有些事情,泛型真做不了。
泛型类型能不能实例化?
1
| T test = new T(); // ERROR
|
因为在 Java 编译期没法确定泛型参数化类型,也就找不到对应的类字节码文件,所以自然就不行了。
此外由于T
被擦除为 Object
,如果可以 new T()
则就变成了 new Object()
,失去了本意。
泛型数组
泛型数组相关的申明:
1 2 3 4 5 6
| List<String>[] list11 = new ArrayList<String>[10]; List<String>[] list12 = new ArrayList<?>[10]; List<String>[] list13 = (List<String>[]) new ArrayList<?>[10]; List<?>[] list14 = new ArrayList<String>[10]; List<?>[] list15 = new ArrayList<?>[10]; List<String>[] list6 = new ArrayList[10];
|
因为在 Java 中是不能创建一个确切的泛型类型的数组的,除非是采用通配符的方式且要做显式类型转换才可以。
需要说明的是, 只是不允许创建这些数组, 而声明类型为 ArrayList<String>[]
的变量仍是合法的。不过不能用 new ArrayList<String>[10]
初始化这个变量。
因为
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Pair<String>[] pairs = new Pair<String>[10];
Pair[] pairs = new Pair[10];
Pair[] pairs = new Pair[10]; Object[] objects = pairs; objects[0] = "123";
|
讨巧的使用场景
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class GenericsDemo30{ public static void main(String args[]){ Integer i[] = fun1(1,2,3,4,5,6) ; fun2(i) ; } public static <T> T[] fun1(T...arg){ return arg ; } public static <T> void fun2(T param[]){ System.out.print("接收泛型数组:") ; for(T t:param){ System.out.print(t + "、") ; } } }
|
如何实例化一个泛型类和泛型数组
如果我们确实需要实例化一个泛型,应该如何做呢?反射!
1 2 3 4 5 6 7 8 9 10
| class Main{ static <T> T newTclass (Class < T > clazz) throws InstantiationException, IllegalAccessException { T obj = clazz.newInstance(); return obj; }
public static void main(String[] args) throws IllegalAccessException, InstantiationException { String s = newTclass(String.class); } }
|
那我们如何实例化泛型数组呢?还是反射!
我们可以通过使用 java.lang.reflect.Array.newInstance(Class<T> componentType, int length)
方法来创建一个具有指定类型和维度的数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class ArrayWithTypeToken<T> { private T[] array;
public ArrayWithTypeToken(Class<T> type, int size) { array = (T[]) Array.newInstance(type, size); }
public void put(int index, T item) { array[index] = item; }
public T get(int index) { return array[index]; }
public T[] create() { return array; } }
class Main{ public static void main(String[] args) throws IllegalAccessException, InstantiationException { ArrayWithTypeToken<Integer> arrayToken = new ArrayWithTypeToken<Integer>(Integer.class, 100); Integer[] array = arrayToken.create(); } }
|
如何理解泛型类中的静态方法和静态变量?
泛型类中的静态方法和静态变量不可以使用泛型类所声明的泛型类型参数
1 2 3 4 5 6
| public class Test2<T> { public static T one; public static T show(T one){ return null; } }
|
因为泛型类中的泛型参数的实例化是在定义对象的时候指定的,而静态变量和静态方法不需要使用对象来调用。
对象都没有创建,如何确定这个泛型参数是何种类型,所以当然是错误的。
但注意区分以下情况:
1 2 3 4 5 6
| public class Test2<T> {
public static <T >T show(T one){ return null; } }
|
因为这是一个泛型方法,在泛型方法中使用的T是自己在方法中定义的 T,而不是泛型类中的T。
__END__