在线html网站开发个人可以建门户网站吗
1.什么是泛型
a.定义
        i.如果不用泛型定义,在使用ArrayList时需要为每个class编写特定类型代码。
         ii.泛型就是定义一种模板,既实现了编写一次,万能匹配,又通过编译器保证了类型安全。
         iii.编写模板代码来适应任意类型。


b.向上转型
        i.带有泛型的类如果存在继承关系可以向上转型,泛型本身不可以直接向上转型。
         ii.特别注意:ArrayList<Integer>和ArrayList<Number>两者完全没有继承关系。
         iii.可以把ArrayList<Integer>向上转型为List<Integer>(T不能变!),但不能把ArratList<Integer>向上转型为ArrayList<Number>(T不能变成父类)。


2.使用泛型
a.优势
        i.不指定时泛型类型默认为Object,需要强制转型,可能出现类型转换错误,很不方便。
         ii.使用泛型时,把泛型参数<T>替换为需要的class类型。
b.泛型接口
        i.除了在class中使用泛型,还可以在接口中使用泛型。例如:Arrays.sort(Object[] o)可以对任意数组排序,但是待排序的元素必须实现Comparable<T>这个泛型接口。
         ii.可以在接口中定义泛型类型,实现此接口的类必须实现正确的泛型。




3.编写泛型
a.编写泛型类
        i.泛型类一般用在集合中,我们很少编写。
         ii.编写泛型时,需要定义泛型类型<T>。

b.静态方法
        i.类定义的泛型类型不能用于静态方法,即不可用于静态方法的返回值和参数。
         ii.对于静态方法,可以单独改写为“泛型”方法,使用另一个泛型,把静态方法和实例方法的泛型类型区分开。

c.多个泛型类型
        i.希望不总是存储相同类型的对象,就可以定义多个泛型。
         ii.java标准库的Map<K,V>就是使用两种泛型的例子。他对Kety使用一种类型,对Value使用另一种类型。

4.擦拭法
a.含义
        i.Java的泛型实现方式是擦拭法,虚拟机对泛型一无所知,所有工作都是编译器做的。
         ii.Java使用擦拭法实现泛型。
                 1.编译器把类型<T>视为Object。
                 2.编译器根据<T>实现安全的强制类型转换。
b.编译器和虚拟机看到的代码区别
        i.编写泛型
                 1.编译器看到的

2.JVM看到的

        ii.使用泛型
                 1.编译器看到的

2.JVM看到的

iii.总结:Java的泛型是由编译器在编译期间实行的,编译器内部永远把所有类型T都视为Object处理;在需要转型时,编译器会根据T类型实现安全的强制类型转换。
c.局限性
        i.<T>不能是基本数据类型,T实际类型是Object,Object无法持有基本数据类型。
         ii.不能取得带泛型类型的Class,无论T是什么类型,返回的永远是Pair当前类的这个Class实例,而不是T的Class。

        iii.不能判断带泛型类型的类型,都是Object。
         iv.不能实例化T,如果要实例化需要传入具体的数据类型。


d.泛型继承
i.一个类可以继承自一个泛型类。
 ii.直接带泛型的类,无法获取到T类型,但是在父类是泛型的情况下,编译器就必须把T保存到子类的class文件中,不然编译器不知道intPair中只能存取Integer类型,所以在继承了泛型情况下,子类可以获取父类的泛型类型。

iii.因为引入了泛型,所以只用class来标识类型已经不够了。

5.extends通配符(上界通配符(Upper Bounds Wildcards))
a.使用方式
i.Pair<Integer>不是Pair<Number>的子类。


ii.Pair<? extends Number>:泛型类型的上界限定为Number,可以是Number或Number的子类的pair类型。

b.只读不写
        i.<? extends Number>:通配符做为方法参数时,当前方法只可以获取不可以传入(null除外),只读不写。
         ii.因为擦拭法。


c.总结
        i.使用<? extends Number>做为方法参数时:
                 1.方法内部可以调用获取Number引用的方法:Number num=obj.getFirst();。
                 2.方法内部无法调用传入Number引用的方法(null除外):obj.setFitst(Number n);
         ii.extends通配符只读不写。
6.super通配符
a.使用方法
        i.Pair<Integer>不是Pair<Number>的子类。
         ii.Pair<? super Integer>:泛型类型可以是Integer或Integer的父类的Pair类型。


 b.只写不读
 
        i.<? super Integer>:通配符做为方法参数时,当前方法只可以传入不可以读取(Object接收除外),只写不读。
         ii.向下转型时本就不安全,需要instanceof判断。
         iii.因为擦拭法。

c.对比extends和super通配符
        i.<? entends T>:只读不写(写时可传入null)。
         ii.<> super T>:只写不读(读时可返回Object)。
d.PECS原则(Producer Extends Consumer Super)
i.如果需要返回T,它是生产者,需要使用extends通配符;如果需要写入T,它是消费者,需要使用super通配符。
e.无限定通配符(Unbounded Wildcard Type)
        i.既没有extends又没有super,所以<?>既不能读也不能写。
         ii.不能调用set(T),传入null除外。
         iii.不能调用T get(),object获取除外。
         iv.Pair<?>是所有Pair<T>的超类。
f.总结
        i.使用<? super Integer>做为方法参数时:
                 1.方法内部可以调用传入Integer引用的方法:obj.setFirst(Integer i);。
                 2.方法内部无法调用获取Integer引用的方法(Object除外):Integer i = obj.getFirst();。
         ii.super通配符只写不读。
         iii.使用extends和super通配符要遵循PESC规则。
         iv.无限定通配符<?>很少使用,既不能读也不能写,可以用<T>替换,同时它是所有<T>的超类。
