泛型总结

 

在JDK1.5 以前,如果把数据存入到集合的时候,需要去判断类型是否合法,假如定义了一个List类型的集合,先向其中加入了两个字符串类型的值,随后加入一个Integer类型的值。这是完全允许的,因为此时list默认的类型为Object类型。在之后的循环中,由于忘记了之前在list中也加入了Integer类型的值或其他编码原因,编译是可以的,但是运行时就会报出ClassCastException,这是严重的安全隐患,而在1.5之后,引入了泛型并且使用了泛型之后,这个隐患在编译时期就被暴露出来,便于开发者去避免这种隐患,也避免了进行强制转换。可以把泛型理解为是java的一种安全机制,对于使用会更方便

 

泛型的定义:

第一种:定义在类 或者接口上边。把尖括号放在类名后边.访问区域是整个类里边,但是,静态方法无法访问这个泛型。

注意:跟在类后边,是用来声明一个泛型的。其他地方不是赋值,就是使用

第二种: 定义在方法上。规则:定义在修饰符之后,返回值之前。

 

如:自定义的泛型

public class Holder<LOL> {

LOL o;

public void set(LOL t) {

this.o = t;

}

public LOL get()

{

return this.o;

}

public static <LOL> void print(LOL l)

{

System.out.println(l);

}

}

自定义的泛型,可以理解为一个变相的类这里面的规则都是自定义的规则,使用起来会更方便

 

对于自定义泛型的几种使用方法:

什么时候赋予具体的数据类型:用的时候,就要赋予数据类型 --不一定为具体的数据类型

类的泛型:

1、在这个类创建的时候,泛型有了具体的数据类型

2、在这个类被实现的时候,必须给与这个需要泛型的类一个数据类型。 

可以为一个具体的数据类型,也可以是一个新的泛型,如果没显示的设置数据类型,则默认父类的泛型里使用Object

方法的泛型:

是在调用的时候,有了具体的数据类型

 

 

 

 

 

 

 

 

 

 

通配符:

把泛型参数理解成方法参数,当我们的对象类型不明确时可以用一个通配符”?”来表示,通配符代表任意类型,相当于是一个占位符,执行的时候回被具体的类型所替代。看一个例子,加入想实现一个能够遍历所有类型的ArrayList的通用方法,由于实现前并不知道到底有多少类型我们需要打印,而使用Object又可能导致ClassCastException,此时通配符的优势便出现了

 

 

 

使用通配符:

 

 

泛型的限定

-------------------------上限<? extends E>,下限<? super E> 

 

由于泛型不支持向上转型

使用通配符就能解决基本上的问题,通用遍历简单类型的集合,但是要保存的是对象呢?要遍历的对象之间又存在继承关系呢?很明显通配符当然可以,但是并不是所有类型的数据我们都想要的,我们想只要有关系的类型(继承关系)。

 

格式:

<? extends E> : E类型或者是E类型的子类: 限定类型的上限.

<?>  等价于  <? extends Object>

<? super E> : E类型,或者E类型的父类 : 限定了类型的下限 

写在泛型定义的时候

格式:<E extends Person>  泛型E只能接受Person以及Person的子类

之前的定义方式<E> 就相当于  <E extends Object>

 

<E extends Student> 这样泛型E就只能接受Student以及Student的父类

 

这是 不使用限定的情况下遍历的:

 

因为泛型无法自动向上转型! ! !

 

 

 

这是使用泛型限定之后的效果:

 

 

对于泛型的限定来说,同时也可以在初始化把限定条件加上

1、 类上的泛型限制

class Holder<T extends Person>

{

 

}

2、方法上的泛型限制:

public static <T extends Person> void print(T  t)

{

}