6 java泛型总结

来源:互联网 发布:全球高清网络电视直播 编辑:程序博客网 时间:2024/06/05 04:31

1 简介
泛型即“参数化类型”。
自定义泛型接口、泛型类和泛型方法。
泛型类型在逻辑上看似看成是多个不同的类型,实际上都是相同的基本类型。

2 基本用法
1)泛型类
泛型之前使用Object类,但是Object类强制转化为其他类时容易出错。

package javazongjie;public class Holder<T> {    private T t;    public Holder(T t) {        super();        this.t = t;    }    public T getT() {        return t;    }    public void setT(T t) {        this.t = t;    }    public static void main(String[] args) {        Holder<String> holder = new Holder<>("Hello T!");        System.out.println(holder.getT());    }}

泛型使得代码更简便安全。

2)泛型方法

package javazongjie;public class GenericMethod {    public <K,V> void f(K k,V v) {        System.out.println(k.getClass().getSimpleName());        System.out.println(v.getClass().getSimpleName());    }    public static void main(String[] args) {        GenericMethod genericMethod = new GenericMethod();        genericMethod.f(new Integer(1), new String("abc"));        //>>Integer        //>>String    }}

3 类型擦除
1)什么是类型擦除
类型参数只存在于编译期,在运行时,Java的虚拟机(JVM)并不知道泛型的存在。

package javazongjie;import java.util.ArrayList;public class ErasedTypeEquivalence {    public static void main(String[] args) {        Class c1 = new ArrayList<String>().getClass();        Class c2 = new ArrayList<Integer>().getClass();        System.out.println(c1 == c2);        //>>true        //在JVM看来它们是同一个类    }}

2) 擦除带来的问题

package javazongjie;public class HasF {    public void f() {        System.out.println("HasF.f()");    }}
package javazongjie;public class Manipulator<T> {    private T obj;    public Manipulator(T obj) {        super();        this.obj = obj;    }    public void manipulate() {        obj.f();        //编译出错    }}

解决办法:
加上一个边界

package javazongjie;public class Manipulator<T extends HasF> {    private T obj;    public Manipulator(T obj) {        super();        this.obj = obj;    }    public void manipulate() {        obj.f();    }}

3)类型擦除的补偿
任何在运行期需要知道确认类型的代码都无法工作。

4 泛型数组

1)如何创建泛型数组

package javazongjie;public class ArrayOfGeneric {    static final int SIZE = 100;    static Holder<Integer>[] holder;    public static void main(String[] args) {        //holder = new Holder<Integer>[SIZE];//编译错误        holder = (Holder<Integer>[])new Holder[SIZE];        System.out.println(holder.getClass().getName()); //输出[Ljavazongjie.Holder;        //成功创建泛型数组的唯一方式是创建一个类型擦除的数组,然后转型        holder[0] = new Holder<Integer>(1);    }}

2)使用 T[] array

package javazongjie;public class GenericArray<T extends Integer> {    private T[] array;    @SuppressWarnings("unchecked")    public GenericArray(int sz) {        array = (T[])new Integer[sz];     }    public void put(int index, T item) {        array[index] = item;    }    public T get(int index) {         return array[index];     }    public T[] rep() {         return array;     }         public static void main(String[] args) {        GenericArray<Integer> gai =        new GenericArray<Integer>(10);        gai.put(0, 100);        System.out.println(gai.get(0));    }}

3 使用反射

package javazongjie;import java.lang.reflect.Array;public class GenericArrayWithTypeToken<T> {    private T[] array;    public GenericArrayWithTypeToken(Class<T> type, int sz) {        array = (T[])Array.newInstance(type, sz);    }    public void put(int index, T item) {        array[index] = item;    }    public T get(int index) { return array[index]; }    public T[] rep() { return array; }    public static void main(String[] args) {        GenericArrayWithTypeToken<Integer> gai =        new GenericArrayWithTypeToken<Integer>(        Integer.class, 10);        Integer[] ia = gai.rep();        System.out.println(ia);    }}

5 数组的协变

class Fruit {}class Apple extends Fruit {}class Jonathan extends Apple {}class Orange extends Fruit {}public class CovariantArrays {    public static void main(String[] args) {               Fruit[] fruit = new Apple[10];        fruit[0] = new Apple(); // OK        fruit[1] = new Jonathan(); // OK        // Runtime type is Apple[], not Fruit[] or Orange[]:        try {            // Compiler allows you to add Fruit:            fruit[0] = new Fruit(); // ArrayStoreException        } catch(Exception e) { System.out.println(e); }        try {            // Compiler allows you to add Oranges:            fruit[0] = new Orange(); // ArrayStoreException        } catch(Exception e) { System.out.println(e); }        }} /* Output:java.lang.ArrayStoreException: Fruitjava.lang.ArrayStoreException: Orange*///:~

6 使用通配符
1)上边界限定通配符

<? extends Fruit>

2)下边界限定通配符

? super T
0 0
原创粉丝点击