泛型就是类型参数化,处理的数据类型不是固定的,而是可以作为参数传入。
1、泛型类、泛型接口
class/interface 类名/接口名 <变量名>{
//变量名只要符合java
}
2、泛型方法
2.1 自己声明泛型类:
//定义在返回类型和权限修饰符之间
public class Caculate { public <T> T add(T num){ return num; } }
2.2 依赖外围类
//在类上定义的E
public E get(){ }
3、泛型通配符
当我们声明一个方法时,某个形参的类型是一个泛型类或泛型接口类型,但是在声明方法时,又不确定该泛型实际类型,我们可以考虑使用类型通配符。
注意:带通配符的List仅表示它可以接受指定了任意泛型实参的List,并不能把元素加入其中
public static void test3(List<?> c){ for (int i = 0; i < c.size(); i++) { System.out.println(c.get(i)); } }
通配符上限(<? extends Type>),通配符下限(<? super Type>)
public static void printArea(List<? extends Graphic> graphics){ for (Graphic g : graphics) { System.out.println(g.getArea()); } }
原理
泛型出现在代码的编译期,对于jvm来说是不存在泛型的。因为在编译器把<T>、<E>等,大部分替换为Object,另一种情况例如<? extends String> 就会替换成String,这是根据上限来相应作出改变。
疑惑:List<Integer>若编译后Integer变为Object,怎么从容器中取出的数还是Integer类型?编译器,做了类型强制转化,记录了之前的类型,当获取时后台会自动强制转化为Integer。