泛型在集合中的应用很广。
泛型 出现jdk1.5
泛型的好处
1、将运行时的问题提前至编译时。
2、避免了无谓的强制类型转换,尤其是从集合中get出元素时
泛型在集合中的常见应用
ArrayList<String> list = new ArrayList<String>(); true
ArrayList<Object> list = new ArrayList<String>(); false
ArrayList<String> list = new ArrayList<Object>(); false
//一下两种的写法主要是为了兼容新老系统的兼容性
ArrayList<String> list = new ArrayList(); true
ArrayList list = new ArrayList<String>(); true
注意:泛型没有多态的概念,左右两边的数据类型必须一致,或者只写一边的泛型。
但是还是推荐使用两边都写泛型的写法。
需求:定义一个方法,可以接受任意类型的参数,而且返回值的类型必须要与实参的类型一致
自定义泛型:就是一个数据类型的占位符,或者一个数据类型的变量
方法上自定义泛型:
修饰符 <声明自定义的泛型>返回值类型 函数名(使用自定义泛型)
{
当然方法体内也可以使用自定义的泛型
}
注意泛型中不能使用基本数据类型,如果要使用基本数据类型的话,应当使用对应的包装类型
byte————>Byte
short————>Short
int————>Integer
long————>Long
float————>Float
double————>Double
boolean————>Boolea
char————>Character
方法泛型的注意事项:
1、在方法上自定义泛型,这个自定义泛型的具体的数据类型是在调用方法的时候传入的实参确定具体的数据类型。
2、自定义泛型只要符合标识符的命名规则即可,但是自定义泛型一般我们都习惯使用一个大写字母表示。T,K, E最常用
泛型类整个类的能不都可以使用自定义个泛型
泛型类的定义格式:
Class 类名<声明自定义泛型>
{
类的内部使用自定义泛型的地方无需声明
}
泛型类的注意事项:
1、在类上自定义泛型的具体数据类型是使用该类创建对象的时候确定的。
2、如果一个类在类上已经声明了自定义泛型,如果使用该类创建对象的时候,没有指定具体的数据类型,默认为Object类型。
3、在类上自定义泛型不能作用于静态的方法,如果静态的方法需要自定义泛型,需要在方法上声明使用,也就是说只能是在方法上行使用泛型。Public static <T> void print(T[] t)这种形式。
泛型接口
泛型接口的定义格式:
interface 接口名<声明自定义泛型>
{
}
泛型接口的注意事项
1、接口上自定义的泛型的具体的类型是在实现(implements)一个接口的时候指定的。
2、在接口上自定义的泛型如果在实现接口的时候没有指定具体的数据类型,默认为Object类型。
需求:目前我实现一个接口的时候,我还不明确要操作的数据类型,我要等到创建这个接口实现类的时候才能指定泛型的具体数据类型
如果要延迟接口自定义类型的具体数据类型格式如下:
public class Demo4<T> implemnts Dao<T>
{
}
泛型的上下限
需求:定义一个函数可以接受任意类型的集合对象,要求接受的集合对象只能存储Integer或者是Integer的弗雷类型的数据。
泛型中的通配符是一个 ? 可以匹配任意类型,通配符一般不会单独使用。
Public void print(Collection <? Super Integer> c)
{
这样写的意思就是我不知道 ? 到底是什么数据类型,但是我知道,它必须是Integer类型或者是Integer类型的父类,此称为泛型的下限。
}
需求:定义一个函数可以接受任意类型的集合对象,要求接受的集合对象只能存储Number或者是number的子类类型的数据。
泛型中的通配符是一个 ? 可以匹配任意类型,通配符一般不会单独使用。
Public void print(Collection <?extends Number> c)
{
这样写的意思就是我不知道 ? 到底是什么数据类型,但是我知道,它必须是Integer类型或者是Integer类型的父类,此称为泛型的上限。
}
泛型内容小总结
看到array,就要想到角标。
看到link,就要想到first,last。
看到hash,就要想到hashCode,equals.
看到tree,就要想到两个接口。Comparable,Comparator