泛型有三个作用:
1.通过泛型的语法定义,约束集合元素的类型,编译器可以在编译期提供一定的类型安全检查,避免运行时才暴露bug。
2.代码通用性更强,后面有案例
3.泛型可以提升程序代码的可读性,但它只是一个语法糖(编译后这样的东西就被删除,不出现在最终的源代码中),对于JVM运行时的性能是没有任何影响的。
泛型的定义
1.定义在类上或者接口上
注意:
1.1 泛型写在类名/接口名之后,大括号之前.
1.2 <>小括号括起来
1.3 类或接口上定义了泛型,则方法上可以直接使用
1.4 泛型名称可以随意取,但是我们一般规定取如下类型的名字.
1.5 可以同时声明几个泛型
一些常用的泛型类型变量:
E:元素(Element),多用于java集合框架
K:关键字(Key)
N:数字(Number)
T:类型(Type)
V:值(Value)
//泛型类
class Person<b>{}
//泛型接口
interface Person2<q>{
q get(); //因为在接口上定义了泛型,方法上可以直接用.泛型方法,返回值泛型
void set(q q1);//泛型方法,参数泛型
}
interface Task<Param,Result>{//一次声明2个泛型
Result execute(Param param);
}
2.泛型定义在方法上
注意:
1.类上没有声明泛型,方法上不能直接用,必须得在修饰符之后,返回值之前声明泛型.
2.声明的泛型,可以用在方法的返回值和方法的参数上
//泛型方法必须的在方法的返回值前加泛型
//泛型方法必须的在方法的返回值前加泛型
static<T> T method(T d) {
return d;
}
3.泛型用在集合上
泛型用在集合上,限定集合中存放数据的类型.
List<String> list = new ArrayList<>();
Map<String,Object> map = new HashMap<>();
泛型擦除/泛型推断
因为泛型是约定编译器的语法格式,在运行期泛型会自动丢弃,故我们可以用反射来验证泛型擦除.
验证思路:
1.创建一个泛型约定为String的ArrayList.
2.直接往ArrayList中添加int类型,报错.泛型约束起作用.
3.通过反射,在运行阶段修改ArrayList的泛型约束为int类型.
4.反射执行方法,添加100成功. 上述验证了,泛型只在编译期间有效,在运行期无效.
public class TestFanXing {
public static void main(String[] args) throws Exception {
List<String> list=new ArrayList<>(); //泛型推断,前面约定了泛型为String,后面可以不用约定了
list.add("Abc"); //添加字符串
list.add(100); //直接添加会报错误
//在运行时将100写入到list集合
//1.获取list对象的字节码对象
Class<?> cls=list.getClass();
//2.获取list字节码对象中的add方法对象泛型擦除,在运行阶段修改add方法的参数类型为int
Method method=
cls.getDeclaredMethod("add",int.class,Object.class);
//3.通过反射执行方法对象将100写入集合。
//执行list对象的method方法
//method.invoke(list, 100);
method.invoke(list, 0,100);
System.out.println(list);
}
}
泛型通配符?
>表示没有限定的泛型; extends Object>约定类型必须为Object的子类; super String> 约定类型必须为String类的父类;
public int size() {
Class<?> cls=list.getClass();
List<? extends Object> list=new ArrayList<String>();//String是Object的子类
List<? super String> list2=new ArrayList<Object>();//Object是String的父类
return 0;
}
继承泛型类或实现泛型接口
/**
* 1.分析如下泛型定义是否正确?
* 1)class A{} 正确
* 2)interface B{} 正确
* 3)class C{
* public void doMethod(T t){} 正确
* }
* 4)class D{ //不正确(类上泛型不作用于静态方法)
* static void doMethod(T t){}
* }
*
* 2.分析如下代码,检查代码是否有问题?
* class A{}
* class B extends A{} 不正确
* class C extends A{}正确
* class E extends A{}正确
*
*3.分析如下代码,检查代码是否有问题?
* interface A{}
* class B implements A{} 不正确
* class C implements A{} 正确
* class D implements A{}正确
* class E implments A{}正确
*
* 4.分析如下代码,检查代码是否有问题?
* List