Java泛型深入(一)

来源:互联网 发布:传奇世界h5源码 编辑:程序博客网 时间:2024/06/06 08:33

一.定义泛型接口,类

泛型的实质:允许在定义接口,类,方法时声明类型形参,这个类型形参将在声明变量,创建对象,调用方法时动态的指定,几乎所有可使用普通类型的地方都都可以使用这种类型形参。

例如 Java5改写后的List接口:

<span style="font-size:18px;"><span style="font-size:18px;">public interface List<E>{//定义接口时指定了一个类型形参,名为Evoid add(E x);Iterator<E> iterator();...}</span></span>

如果为E传入String类型实参,则产生了一个新类型:List<String>类型,可以认为List<String>是List的子接口


我们可以为任何类,接口添加泛型声明,,例如Apple类:

<span style="font-size:18px;">package genericity;import structurerOverride.Apple;public class Applee<T> {private T info;public T getInfo() {return info;}public void setInfo(T info) {this.info = info;}public Applee() {}public Applee(T info){this.info=info;}public static void main(String[] args) {//由于传给T形参的是String,所以构造器参数只能是String Applee<String> a1=new Applee<>("苹果"); System.out.println(a1.getInfo());//由于传给T形参的是Double,所以构造器参数只能是Double Applee<Double> a2=new Applee<>(2.5);  System.out.println(a2.getInfo());}}</span>

这样在使用Apple<T>时就可以为T类型传入多个类型,生成形如Apple<String>,Apple<Double>...的多个逻辑子类

(虽然并没有什么实际意义)


二.从泛型类派生子类

当使用接口,父类时不能再包含类型形参 例如下面的代码是错误的

<span style="font-size:18px;"><span style="font-size:18px;">public class A extendds Aapple<T>{ }</span></span>
如果想从Apple类派生一个子类,可以改为如下代码:

<span style="font-size:18px;"><span style="font-size:18px;">public class A extendds Aapple<String>{ }</span></span>
此时Apple类中所有使用T类型的地方都将被替换成String类型

三.实际上并不存在泛型类,我们只是逻辑上这么称呼

例如:

List<String> l1=new ArrayList<>();List<Integer> l2=new ArrayList<>();System.out.println(l1.getClass()==l2.getClass());

可能有读者认为会输出false,但实际上输出true,因为不管泛型的实际类型是什么,它们在运行时总有同样的类

不管为泛型的类型形参传入哪一种类型实参,对于Java来说,它们依然被当成同一个类处理,在内存中也只占用一块内存空间,因此在静态方法,静态初始化块或静态变量的声明和初始化时不允许使用类型形参


类型通配符将在下一篇记下





0 0