泛型,即“参数化类型”;参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参,如果调用方法时实参不对,编译器会直接报错。同样,“参数化类型”的泛型也是让我们在编译的时候就能知道传入的实参类型是否是指定的类型,比如指定ArrayList中元素都是String类型的,就不能传入一个int型值,会编译通不过;另外,泛型也增强了代码的复用性。
泛型特性:泛型只在编译阶段有效;
泛型有三种使用方式,分别为:泛型类、泛型接口、泛型方法;泛型类,是在实例化类的时候指明泛型的具体类型;泛型方法,是在调用方法的时候指明泛型的具体类型。
泛型类:T就是实例化这个类所需要指定的类型;仅该类型,与其子类父类没有关系,统统不匹配;
public class haha<T>{
T value;
haha(T value){
this.value = value;
}
T getValue(){//这个不是泛型方法哦,这只是普通的方法;泛型方法至少是<T>,即需要有这个泛型声明
return value;
}
}
泛型接口
泛型方法:
比如:
* 1)public 与 返回值中间<T>非常重要,可以理解为声明此方法为泛型方法。
* 2)只有声明了<T>的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。
* 3)<T>表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。
public T genericMethod(Class tClass)throws InstantiationException ,
IllegalAccessException{
T instance = tClass.newInstance();
return instance;
}
比如:泛型类中再加上泛型方法
classGenerateTest{
publicvoid show_1(T t){
System.out.println(t.toString());
}
//在泛型类中声明了一个泛型方法,使用泛型E,这种泛型E可以为任意类型。可以类型与T相同,也可以不同。
//由于泛型方法在声明的时候会声明泛型<E>,因此即使在泛型类中并未声明泛型,编译器也能够正确识别泛型方法中识别的泛型。publicvoid show_3(E t){
System.out.println(t.toString());
}
//在泛型类中声明了一个泛型方法,使用泛型T,注意这个T是一种全新的类型,可以与泛型类中声明的T不是同一种类型。publicvoid show_2(T t){
System.out.println(t.toString());
}
}
注意:泛型类中的静态方法如何处理
publicclassStaticGenerator {
....
....
/** * 如果在类中定义使用泛型的静态方法,需要添加额外的泛型声明(将这个方法定义成泛型方法)
* 即使静态方法要使用泛型类中已经声明过的泛型也不可以。
* 如:public static void show(T t){..},此时编译器会提示错误信息:
"StaticGenerator cannot be refrenced from static context"
*/publicstaticvoid show(T t){
}
}
详情:https://www.cnblogs.com/coprince/p/8603492.html
泛型的上下边界
1、无边界:?可以接受任何的实际类型作为泛参;
2、上边界:上界通配符为”extends”,可以接受其指定类型或其子类作为泛参;
3、下边界:下界通配符为”super”,可以接受其指定类型或其父类作为泛参;
参考:https://blog.csdn.net/renwuqiangg/article/details/51296621