JDK1.5才出现的。
所谓泛型:就是允许在定义类、接口时指定类型形参,这个类型形参将在声明变量
创建对象时确定(即传入实际的类型参数,也可称为类型实参)
包含泛型声明的类型可以在定义变量,创建对象时传入一个类型实参,从而可以动态的
生成无数多个逻辑上的子类,但这种子类在物理上并不存在
这里有一个值得注意的是当你创建带泛型声明的自定义类,为该类定义构造器时,构造器名
还是与与原来的类名,不要增加泛型声明。例如为Apple<T>类定义构造器,其构造器名依然
是Apple,而不是Apple<T>,但调用该构造器时却可以使用Apple<T>的形式,当然应该为T形参传入实际的类型参数。
畸形写法:
1. List<String> list=new ArrayList();
2. List list=new ArrayList<String>();
JDK1.7开始支持 List<String> list=new ArrayList(); 这么写,可以从前往后推到出后面具体的类型
泛型的擦除:泛型类型由可以支持任意数据类型到具体的类型,发生在java的编译时期
public class fanxing { public static void main(String[] args) { TDemo<String> t=new TDemo<String>(); t.t="徐旺骑"; } } //自定义泛型类 //类名<标识符> //虽然可以随便写,但是我们通常用大写字母 /* * E ----elements元素 * T---- Type类型 * R----Result结果 * K-----键 * V-----值 * */ class TDemo<E>{ //属性 E t; //属性类型可以是任意的引用类型 //E t1=new E();这是错误的给定的引用类型可能不能创建对象例如:接口类型 //泛型方法 public <E>void name(E i) { //泛型做参数类型 }
2.从泛型类派生子类
当创建了带泛型声明的接口、父类之后,可以为该接口创建实现类,或从该父类来派生子类,但值得提出的时,当使用这些接口、父类时不能再包含类型形参,例如下面代码时错误的:
public class Fanxing extends Apple<T> { //这个是错的不能用类型形参 public static void main(String[] args) { } } class Apple<T>{ } class A extends Apple<String>{ //用类型实参这个是对的 }
3.ArrayList<String>类当成ArrayList的子类,事实上ArrayList<String>类也确实是一种特殊的
ArrayList类,这个ArrayList<String>对象只能添加String对象作为集合元素,但实际上系统并没有为
ArrayList<String>生成新的class文件,而且也不会把ArrayList<String>当成新类来处理
需要一个泛型参数既可以接收Double类型,又可以接收Integer类型,照理来讲我们可以找到这两个类的父类Number,做向上转型。但是泛型没有向上转型,这就比较的尴尬。所以为了满足我们的需求就有了
重点
类型通配符?:
?:被称之为统配符,他的元素类型可以匹配任何类型
泛型的上限和泛型的下限。
public static void main(String[] args) { //集合对象 List<Integer> list1=new ArrayList<>(); // list1.add(113); list1.add(3); list1.add(1); list1.add(1); list1.add(11); //集合对象 List<Double> list2=new ArrayList<>(); // list2.add(1.2); list2.add(3.0); list2.add(6.3); list2.add(1.2); list2.add(1.1); //List<Number> list=new ArrayList<Integer>(); //泛型没有向上造型 m(list1); m(list2); //m(new ArrayList<String>());//不是数字类型 } //只遍历数字类型的集合 //数字包装类的统一父类是Number //<? extends 类/接口>---可以传入的类型包括本类/本接口或者子类以及子接口 //<? extends Number>---可以传入Number类型或者以及Number的子类 //泛型的上限 public static void m(List<? extends Number> list){//所有元素的数据类型都可以接收 for (Object object : list) { System.out.println(object); } } //泛型下限 //传入的类型最小类型是String //<? super 类/接口>---可以传入的类型要么是本类/本接口或者是父类以及父接口 public void n(List<? super String> list){ }
4.泛型方法 :相当于是来约束方法的参数用的