Java泛型

前言

使用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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值