Java泛型学习四:泛型其它知识点
一.开篇
???? 在学习泛型的过程中,有许多零零碎碎的知识点,它们并不好用单独一篇文章来说,遂罗列如此。
?
二.泛型异常
package com.jyz.study.jdk.generic;/** * 泛型在异常中的限制 * @author JoyoungZhang@gmail.com * */public class GenericException<T extends Throwable> { void test(T t) throws T{//T被擦除到了Throwable, 可以声明形式类型参数这个异常try{ throw t;//T被擦除到了Throwable,这里也可以编译通过}catch(T ex){ //compile error 1.catch块不能捕获泛型类型的异常 //因为在编译器和运行期间都必须知道异常的确切类型,即使知道T被擦除到了Throwable也没用} } void erasureTest(Throwable t) throws Throwable {try{ throw t;}catch(Throwable ex){} }}//compile error//2.泛型类不能直接或间接继承Throwable//并不是说泛型形式类型参数不能继承Throwableclass MyException<T extends Throwable> extends Throwable{}
三.泛型数组
package com.jyz.study.jdk.generic;import java.util.ArrayList;/** * 数组是协变的covarant, Super[]是Sub[]的父类型 * 泛型是不可变的invariant, List<Super>跟List<Sub>没有任何关系 * @author JoyoungZhang@gmail.com * */public class ArrayAndList<T> { void test1(){ Number[] objectArray = new Long[1]; objectArray[0] = 10.10;//运行时java.lang.ArrayStoreException: java.lang.Double } void test2(T t){//List<Number> list = new ArrayList<Long>();//comiple error } //数组和泛型不能很好的混用 //如创建 泛型数组,参数化类型的数组,类型参数的数组都是非法的 void illegal(Object object){//可以按编译器喜欢的方式定义一个泛型数组的引用List<String>[] justAReference;////but 永远是一个引用,不能被实例化//justAReference = new ArrayList<String>()[];//new ArrayList<T>()[];//new T[10];////以下也不能工作//obj instanceof T//new T(); } public static void main(String[] args) { System.out.println(new ArrayList<Number>().getClass()); System.out.println(new ArrayList<Integer>().getClass()); } }?但我们仍然可以有自己的方式创建泛型数组。三种方式参考Thinking in Java P384-386。第三者方式稍作修改如下。
package com.jyz.component.core.collection;import java.lang.reflect.Array;import java.util.Arrays;/** * 泛型数组 * from Thinking in Java page 385 *@author JoyoungZhang@gmail.com * */public class JyzArray<T> {private T[] array;/** * * @param clazz 从擦除中恢复类型,使得我们可以创建需要的实际类型的数组 * 该数组的运行时类型就是确切类型T[],而不是擦除后的Object * @param length 数组长度 */@SuppressWarnings("unchecked")public JyzArray(Class<T> clazz, int length){array = (T[]) Array.newInstance(clazz, length);}/** * put item to index * @param index * @param item * @throws IndexOutOfBoundsException */public void put(int index, T item){RangeCheck(index, array.length);array[index] = item;}/** * * @param index * @return * @throws IndexOutOfBoundsException */public T get(int index){RangeCheck(index, array.length);return array[index];}/** * * @return 泛型数组 */public T[] rep(){return array;}private void RangeCheck(int index, int length) {if (index >= length) { throw new IndexOutOfBoundsException("Index: "+index+", Size: "+length);} }public static void main(String[] args) {JyzArray<Integer> jyzArray = new JyzArray<Integer>(Integer.class, 8);for(int i=0; i<8; i++){jyzArray.put(i, i);}Integer[] array = jyzArray.rep();System.out.println(Arrays.toString(array));}}?
四.泛型重载
????
void f(List<T> v){}void f(List<TT> v){}
?将产生相同的方法签名,编译不通过。
?
五.自限定异常
public class SelfBounded<T extends SelfBounded<T>> { }//基类用导出类作为其实际类型参数class GenericType<T>{}class CuriouslyRecurringGeneric extends GenericType<CuriouslyRecurringGeneric>{}?