首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Java泛型学习4:泛型其它知识点

2013-11-29 
Java泛型学习四:泛型其它知识点一.开篇???? 在学习泛型的过程中,有许多零零碎碎的知识点,它们并不好用单独

Java泛型学习四:泛型其它知识点

一.开篇

???? 在学习泛型的过程中,有许多零零碎碎的知识点,它们并不好用单独一篇文章来说,遂罗列如此。

?

二.泛型异常

    catch语句不能捕获泛型类型的异常,因为在编译器和运行期间都必须知道异常的确切类型。泛型类不能直接或间接继承Throwable,这并不是说泛型形式类型参数不能继承Throwable。
    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{}

三.泛型数组

    ?数组是协变的(covarant), Super[]是Sub[]的父类型。泛型是不可变的invariant, List<Super>跟List<Sub>没有任何关系。以上两点决定了数组和泛型不能很好的混用,如创建 泛型数组,参数化类型的数组,类型参数的数组都是非法的。更多知识点参考代码。
    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){}

?将产生相同的方法签名,编译不通过。

?

五.自限定异常

    ?SelfBounded类接受形式类型参数T,而T有一个边界类限定,这个边界就是拥有T作为形式类型参数的SelfBounded。古怪的循环泛型(CRG)本质:基类用导出类作为其实际类型参数。
    public class SelfBounded<T extends SelfBounded<T>> {                                                                                                                                                                                                                                                                         }//基类用导出类作为其实际类型参数class GenericType<T>{}class CuriouslyRecurringGeneric extends GenericType<CuriouslyRecurringGeneric>{}
    ?

热点排行