目录
为什么要用泛型?
集合中如果存储的是object类型,会引发类型转换问题.集合建议存储同一类类型数据.泛型可以很好的解决问题
什么是泛型?
泛型是jdk5之后引入的语法
泛型--参数化类型,把类型作为参数传递,创建类的对象时,可以传入任意类型
优点:在编译时,能够检查类型安全
public class FDemo {
public static void main(String[] args) {
ArrayList list = new ArrayList<>();
list.add(3);
list.add(2);
list.add(1);
list.add(true);
list.add("1");
for (Object obj : list) {
if (obj instanceof String) {
String s = (String) obj;
} else {
System.out.println(obj);
}
}//String s;
// System.out.println(s.length());
}
}
集合中如果不添加泛型,默认是可以添加任何类型(引用类型)
泛型类
泛型类型用于类的定义中,被称为泛型类
1.泛型的类型参数只能是类类型
2.泛型的类型参数可以有多个
3.如果没有定义具体类型,默认为Object
从泛型类派生子类
public class Demo<T> {
private T num;
public T getNum() {
return num;
}
public void setNum(T num) {
this.num = num;
}
public static void main(String[] args) {
Demo<Double> d = new Demo<>();
d.setNum();
Demo d1 = new Demo();
d1.setNum();
}
private void setNum() {
}
public void show(Demo<?> obj) {
}
public void show1(Demo<? extends T> obj) {
}
public void show2(Demo<?super T>obj){
}
}
/*从泛型类型派生子类:子类也是泛型类,子类和父类的泛型类要一致
子类不是泛型类,父类要明确泛型的数据类型
*/
实际传入的参数类型必须是引用类型
可以有多个泛型
如果没有传入实际的类型,默认为object类型
泛型接口
public class Demo1<T> extends Demo<T> {
public interface Demo<T> {
//子类也是泛型类,子类和父类的泛型类型要一致
class a<T> implements Demo<T> {
}
}
}
public class CDemo extends Demo<Integer> implements Comparable {
public static void main(String[] args) {
CDemo cd = new CDemo();
cd.setNum(10);
}
//子类不是泛型类,父类要明确泛型的数据类型
@Override
public int compareTo(Object o) {
return 0;
}
}
通配符,上边界,下边界
类型通配符一般是使用"?"代替具体的类型实参
?表示实际传入的参数的泛型类型?表示可以是任意的,也称无界通配符
类型通配符上限:
类/接口<?extends 实参类型>
要求该泛型的类型,只能是实参类型,或实参类型的子类类型
类型通配符下限:
类/接口<?super 实参类型>
要求该泛型的类型,只能是实参类型,或实参类型的父类类型
public class CDemo extends Demo<Integer> implements Comparable {
public static void main(String[] args) {
CDemo cd = new CDemo();
cd.setNum(10);
}
//子类不是泛型类,父类要明确泛型的数据类型
@Override
public int compareTo(Object o) {
return 0;
}
}
public class TestDemo {
public static void main(String[] args) {
Demo d=new Demo();
Demo<Integer>di=new Demo<>();
Demo<Number>dn=new Demo<>();
Demo<String>ds=new Demo<>();
Demo<Object>do1=new Demo<>();
d.show(di);
d.show(dn);
d.show(ds);
d.show(do1);
}
}
类型擦除
泛型是Java1.5版本才引进的概念,在这之前是没有泛型的.但是,泛型代码能够很好地和之前版本的代码兼容.那是因为,泛到信息只存于代码编译阶段,在进入JVM之前,与泛型相关的信息会被擦除掉,我们称之为一类型擦除.
泛型类被类型擦除后,相关的类型就是被替换成Object类型或者上限类型.
public class TestDemo2 {
public static void main(String[] args) throws NoSuchFieldException {
Demo<Integer>di=new Demo<>();
di.setNum(10);
di.getNum();
Class c=di.getClass();
Field f=c.getDeclaredField("num");
f.setAccessible(true);
System.out.println(f.getType());
}
}