Java泛型

来源:互联网 发布:陈田村拆车件淘宝店 编辑:程序博客网 时间:2024/04/30 08:44

前言

使用Java的时候,我们都在用泛型,可是泛型究竟是什么,泛型的机制是什么?泛型为什么在运行时不能获取他的类型?泛型中的限定符到底代表什么意义?感觉应该好好了解下泛型的使用。

为什么使用泛型?

通常我们设计一个方法的时候,为了让方法更加通用,我们经常使用的就是多态(父类 接口等)。例如:

    public static void sort(ArrayList list){};    public static void sort(List list){};    public static void sort(Collection collection){};

更明显的就是最后一个方法更加的通用,可以接受任何Collection的子类。
如果想要比接口更大的通用性怎么办?Object or 泛型

泛型的实现原理

Java泛型的核心概念:告诉编译器想使用什么类型,编译器帮助你处理一切的细节。

泛型擦除

由于Java为了能够实现向上兼容性,就不得不保证,在实际运行的时候(机器码)根本不存在泛型这种东西。换言之Java泛型只是个语法糖。并没有修改Java的底层机制。只能在编辑器上做一些处理。

泛型的擦除是擦出到边界

? super List 擦除的边界为List
T 擦除的边界为Object
引用编程思想的话:
泛型中的所有动作都发生在边界处,对传递过来的进行额外的编译检查,并插入对传递出去值的转型
其实这点不是很明白,如果在javac的时候,就体现不出来不同,那么运行的时候,怎么可能转型???不是很明白

        Class c1 = new ArrayList<Integer>().getClass();        Class c2 = new ArrayList<String>().getClass();        //两个不同泛型的类是一个类        System.out.println(c1 == c2);//true        //得到对应的泛型类型竟然是个占位符!!!        //泛型代码内部,无法获取任何有关的泛型参数类型的信息        Arrays.toString(c1.getTypeParameters())//[E]    

擦除的补偿

1.擦除导致了不知道泛型的类型信息,因此只能传递一个类型标签解决(多传递一个Class对象)
2.泛型数组:一班的解决方案是在任何想要创建泛型数组的地方都适 用ArrayList(因为有了擦除,数组的运行时类型只能是Object[])

泛型类和泛型方法的区别

泛型方法使改方法能够独立于类而产生变化,并且可以使用类型推断

    public class New {    public static <T> List<T> list(){        return new ArrayList<T>();    }    public static void main(String[] args) {        //隐式使用类型        List<String> list = list();        //显示使用类型        New.<String>list ();    }}

边界

List<’?’ extends Fruit>:具有任何从Fruit继承的类型的列表,但是不知道这个具体的类型是什么。

? extends Fruit 代表了一种具体的类型,但是木有指定具体类型,只能进行向上转型

public class New {    public static void main(String[] args) {        List<? extends Fruit> list = new ArrayList<>();        //Complier Error:cannot add any type of object        list.add(new Apple());        //Complier Error:cannot add any type of object        list.add(new Fruit());        list.get(1).eat();    }}class Fruit{    void eat(){};};class Apple extends Fruit{};class Banana extends Fruit{};

? super Myclass :代表的是某一个Myclass的超类

public class New {    public static void main(String[] args) {        List<? super Apple> list = new ArrayList<>();        list.add(new Apple());        //Complier Error:cannot add any type of object        list.add(new Fruit());    }}class Fruit{    void eat(){};};class Apple extends Fruit{};class Banana extends Fruit{};

List

public class Holder<T> {    Object o;    T get() {        return (T) o;    }    void set(T t) {        o = t;    }    public static void main(String[] args) {        Holder holder = new Holder();        holder.set(new String("11"));        holder.set(3);        Holder<?> holder2 = new Holder();        //can not complier        holder2.set(3);        Object o = holder2.get();    }}

最后给大家在上一个编程思想的例子:

public static <T, S extends Iterable<? extends T>>    void apply(S seq, Method method,Object... args) {        try {            for (T t : seq) {                method.invoke(t, args);            }        } catch (Exception e) {            throw new RuntimeException(e);        }    }

Java编辑器优化:
http://blog.csdn.net/u010169705/article/details/51288788

0 0
原创粉丝点击