泛型
泛型类、泛型接口、泛型方法
总结:
1.集合接口或者集合类在jdk5.0时都修改为待泛型的结构。
* 2.在实例化集合类时,可以指明具体泛型类型。
* 3.指明完以后,在集合类或者接口中凡是定义类或接口时,内部结构(比如:方法,构造器,属性等)使用 到类的泛型的位置,都指定实例化泛型类型
* 比如: add(E e)--->实例化以后: add( Integer e)
* 4.注意点:泛型的类型必须是类,不能是基本数据类型。需要用到基本数据类型的位置,拿包装类替换
* 5.如果实例化时,没有指明泛型的类型。默认类型为java.Lang.object类型。
*
*
泛型类、泛型接口
* 1.泛型类可能有多个参数,此时应将多个参数一起放在尖括号内。比如:<E1,E2,E3>
* 2.泛型类的构造器如下:public GenericClass()。而下面是错误的: public GenericClass<E>()‘
* 3.实例化后,操作原来泛型位置的结构必须与指定的泛型类型一致。
* 4.泛型不同的引用不能相互赋值。尽管在编译时ArrayList<String>和ArrayList<Integer>是两种类型,
* 但是,在运行时只有一个ArrayList被加载到JVM中。
* 5.泛型如果不指定,将被擦除,泛型对应的类型均按照Object处理,但不等价于Object。经验:泛型要使用一路 都用。要不用,一路都不要用。
* 6.如果泛型结构是一个接口或抽象类,则不可创建泛型类的对象。
* 7. jdk1.7,泛型的简化操作:ArrayList<Fruit> flist = new ArrayList<>();
* 8.泛型的指定中不能使用基本数据类型,可以使用包装类替换。
* 9.在类/接口上声明的泛型,在本类或本接口中即代表某种类型,可以作为非静态属性的类型、非静态方法的参数 类型、非静态方法的返回值类型。
* 但在静态方法中不能使用类的泛型。(因为静态方法是随着类加载的,而泛型是实例化的时候才说明类型,静 态方法要比泛型早)
* 10.异常类不能是泛型的
* 11.不能使用new E[]但是可以:Eelements =(E)new Object[capacity];
* 参考: ArrayList源码中声明:Object[]elementData,而非泛型参数类型数组。
* 12.父类有泛型,子类可以选择保留泛型也可以选择指定泛型类型:
* 子类不保留父类的泛型:按需实现
* 没有类型擦除
* > 具体类型
* 子类保留父类的泛型:泛型子类
* > 全部保留
* 部分保留
* 结论:子类必须是“富二代”,子类除了指定或保留父类的泛型,还可以增加自己的泛型
泛型方法
* 泛型方法:在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系。
* 换句话说,泛型方法所属的类是不是泛型类都没有关系。
* 泛型方法,可以声明为静态的。原因:泛型参数是在调用方法时确定的。并非在实例化类时确定。
* [访问权限] <泛型> 返回类型 方法名([泛型标识 参数名称]) 抛出的异常
1.泛型在继承方面的体现
虽然类A是类B的父类,G<A>和G<B>二者不具备子父类关系,二者是并列关系
补充:类A是类B的父类,A<G>是B<G>的父类
2.通配符的使用
通配符:?
类A是类B的父类,G<A>和G<B>二者不具备子父类关系的,二者共同父类:G<?>
添加(写入):对于List<?>就不能向其内部添加数据
除了添加null
获取(读取):允许读取数据,读取的数据类型为Object
3.有限制条件的通配符使用;
? extends A: G<? extends A> 可以作为G<A>和G<B>的父类,其中B是A的子类
? super A: G<?super A> 可以作为G<A>和G<B>的父类,其中B是A的父类