【Java】泛型(2)

1.为什么使用泛型

主要是因为我们想要编写出与类型无关的代码。

那么实现这个有两种可选的办法:

1.使用Object基类;

2.使用泛型。

为什么方法1不好?原因有两个:

(1)每一次获取实例需要经过类型转换;

(2)没有类型检查。通常而言,我们写的类型无关的代码在使用的时候只会绑定一种具体类型,但是使用了Object,我们其实可以放入任意的类型,这时在获取的时候强转就会报强转失败的异常。而泛型在编译器提供了类型检查,可以把异常从运行期提前至编译期。

2.泛型的使用

分为定义,声明和使用。

定义,采用一个类型参数通常是T作为占位符。T中能被调用的方法默认是Object的方法,因为默认类型擦除以后就是Object。如果想要调用其他方法,就需要为类型参数限定类型,使用extends指定类型参数的父类。那么就可以调用父类的方法了。

声明,也就是定义一个泛型类型实例的静态类型。这里可以使用具体的参数类型,也可以使用“?”或者搭配extends参数泛化。

比如:List<?> list;

声明有时会比较复杂,特别是与定义搭配,比如:

class Container<T extends Comparable<? extends App>>{


}

这里定义了一个反省类,并且限定了参数类型T,必须是comparable接口的实现类。但是comparable接口本身又是一个泛型接口。所以caomparable的泛型限定也要满足。

所以T必须满足上述要求。

比如下面这个就满足:

class AAA implements Comparable<App>{

    @Override
    public int compareTo(App o) {
        return 0;
    }
}

但是下面这个就不满足:

class BBB implements Comparable<String>{

    @Override
    public int compareTo(String o) {
        return 0;
    }
}

因为List<String>和List<integer>是不同的。

类型参数泛化的意义在于,我定义的变量可以被赋值一个arraylist<String>或者arraylist<Integer>类型的实例,都可以处理。

使用,也就是最终为类型参数赋值的时候,这里指定的类型才是类型参数最终的类型。

3.类型擦除

Java虚拟机对于泛型的实现机制就是类型擦除,定义了一个泛型类,最终编译后就只有一个基本类型的类,泛型的类型参数会被擦除。没有extends会用object,反之用基类。

4.桥方法

这是类型擦除与多态冲突的解决机制,在另一篇博客有介绍。

5.一些与泛型有关的问题:

猜你喜欢

转载自blog.csdn.net/u010900754/article/details/81780758