定义
宽泛的类型,参数化类型
是把类型的明确推迟到创建对象或者调用方法时才去明确
格式
<数据类型>
注意点:只能是引用数据类型,重新赋值还是原来的数据类型
优点
错误提前化:编译期间
避免强制类型转化
优化设计,把控可控性,提高安全
(架构师必备最基础条件)
由来
Object 类型作为参数,被取出时需要向下转型,存在极大的安全隐患
定位位置
泛型类:
类名<数据类型,数据类型,数据类型>
数据类型定义要求:仅仅一个字母,且大写
类名<T,K,V>
例如:
public class Person<T> {
public void show(T t) {
System.out.println(t);
}
}
Person p=new Person();
p.show("你好");
//虽然看上去觉得没有使用泛型,但是其实已经用到了泛型
Person<String> p1=new Person<String>();
p1.show("哈哈");
Person<Integer> p2=new Person<Integer>();
p2.show(123);//自动装箱
泛型方法:
<数据类型,数据类型,数据类型> 返回数据类型前,修饰符之后
数据类型定义要求:仅仅一个字母,且大写
类名<T,K,V>
方法形参数据类型和返回类型都可以是泛型:
public static M getInt(M m) {}
例如:
public static <M> M getObject(M m) {
System.out.println("M m : " + m);
return m;
}
GenericParadigm genericParadigm3 = new GenericParadigm();
System.out.println(genericParadigm3.getObject("haha"));
// 放了字符串类型,返回得到的也是字符串类型
String string = genericParadigm3.getObject("haha");
System.out.println(string);
泛型接口:
接口名后 <数据类型>
接口名
接口名 <T,K,V>
例如:
public interface Number<T, K, V> {
public abstract void showNumber(T t);
}
public class NumberImpl<T, K, V> implements Number<T, K, V>{
@Override
public void showNumber(T t) {
System.out.println(t);
}
//接下来再写一些能用上K和V的方法,用不上就不要写上,否则就是冗余代码
}
泛型通配符:
通配符 <?>:问号代表任意引用型数据类型,多态可以用上了
向上(天花板)限定:<? extends Father>
必须是某一个类或者它的子类
向下(地板)限定:<? super Father>
必须是某一个类或者它的父类
例如:
Collection<?> c1=new ArrayList<String>();
Collection<?> c2=new ArrayList<Integer>();
Collection<?> c3=new ArrayList<Boolean>();
Collection<? extends Father> c4=new ArrayList<Son>();
Collection<? extends Father> c5=new ArrayList<Daugther>();
Collection<? extends Father> c6=new ArrayList<Father>();
Collection<? super Father> c7=new ArrayList<Father>();
Collection<? super Father> c8=new ArrayList<Object>();
Collection<? super Son> c10=new ArrayList<Son>();
Collection<? super Son> c11=new ArrayList<Father>();
Collection<? super Son> c12=new ArrayList<Object>();
泛型注意点:
public class Father {
public Father() {}
}
public class Son extends Father {
public Son() {}
}
public class Demo1{
public static void main(String[] args) {
Student<? extends Father> s1= new Student<Son>();
s1.show(new Son());
// 解决方案一:需要在Student中定义泛型类方法
// 解决方案二:
Student<? extends Father> s2= new Student<Son>();
// 修改为:
Student<Father> s2= new Student<Son>();
// 解决方案三:
// 在Student类中新增方法:
void show(Son s){
System.out.println(s);
}
}
}
public class Student<T extends Father> {
/*void show(T t){
System.out.println(t);
}*/
// 解决方案一:
public <M> void show(M t) {
System.out.println(t);
}
// 解决方案三:
// 在Student类中新增方法:
/*void show(Son s) {
System.out.println(s);
}*/
}
泛型类嵌套:
泛型类1:Infor<K,V>
泛型类2:GetInfor
创建对象的时候:GetInfor<Infor<K,V>>
例如:
public class Student<S> {
public <S> void studentShow(S s) {
System.out.println("Student");
}
}
public class Teacher<T> {
public void teacherShow(T t) {
System.out.println("Teacher");
}
}
public class Demo1 {
public static void main(String[] args) {
Teacher<Student<String>> t=new Teacher<Student<String>>();
t.teacherShow(new Student<String>());
}
}