集合-Generic

来源:互联网 发布:淘宝店铺发布产品 编辑:程序博客网 时间:2024/06/10 11:18

当集合中存储的数据类型不同时,可能会导致程序运行的时候转型异常。

2、package CollectionDemo;3、4、import java.util.ArrayList;5、import java.util.Iterator;6、import java.util.List;7、8、public class Demo {9、10、public static void main(String[] args) {11、List<Integer> list=new ArrayList<Integer>();12、list.add(1);13、list.add(2);14、list.add(3);15、//编译时报错16、//list.add("adf");17、System.out.println(list);18、Iterator<Integer> it=list.iterator();19、while(it.hasNext())20、{21、System.out.println(it.next());22、}23、}24、}

当加上对类型的限制以后,将运行时的异常提前至编译时发生。获取元素的时候无需强转类型,就避免了类型转换的异常问题。

当类中操作的引用数据类型不确定的时候,就可以使用泛型类。注:<>中的数据类型必须是引用类型。

泛型

泛型方法

           当写一个函数,调用者传递什么类型的变量,该函数就返回什么类型的变量的时候,因为无法确定传递什么类型的数据,如果不用泛型的话,方法的形参就定义为Object类型,返回值也就是Object类型,但是使用该函数时需要强制类型转换。但是强制类型转换如果每次都判断是什么类型的,然后转换的话执行效率很低,否则可能因为类型不一致而报类型转换异常。所以此时,可以考虑泛型方法。

泛型就是将类型当做变量处理,规范泛型的定义一般是一个大写的任意字母。

函数上的泛型定义方法

         public<泛型的声明> 返回值类型函数名(泛型变量名){}

package CollectionDemo;import java.util.ArrayList;import java.util.List;public class Demo {public static void main(String[] args) {List<Integer> list=new ArrayList<Integer>();list.add(1);list.add(2);list.add(3);System.out.println(new Demo().getData(list));}public <T> T getData(T data){return data;}}

注:使用泛型方法前需要进行泛型声明,该声明位置在static后,返回值类型前。

泛型类

         当一个类中有多个函数声明了泛型,那么该泛型的生命可以声明在类上。

格式:

         修饰符 class 类名<泛型>{}

       

package CollectionDemo;import java.util.ArrayList;import java.util.List;public class Demo<T> {public static void main(String[] args) {List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(2);list.add(3);System.out.println(new Demo().getData(list));}public T getData(T data) {return data;}}

注:静态方法不可以使用类中定义的泛型

因为类中的泛型需要在对象初始化时指定具体的类型,而静态优先于对象存在,那么类中的静态方法就需要单独进行泛型声明。

package CollectionDemo;import java.util.ArrayList;import java.util.List;public class Demo<T> {public static void main(String[] args) {List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(2);list.add(3);System.out.println(Demo.getData2(list));}public  T getData(T data) {return data;}public static<E> E  getData2(E data){return data;}}

继承泛型类的写法

class Parent<T>{public T getData(T t){return t;}}//父类指定了具体的类型,则子类不用再指定类型class Child extends Parent<String>{}//当父类使用了泛型,则子类也需要使用泛型class Child<T> extends Parent<T>{}//错误写法,当父类上定义了泛型,则子类上也需要定义,这里子类没有定义,所以编译出错class Child extends Parent<T>{}

泛型接口

interface Parent<T>{}//父类定义了明确的类型时class Child implements Parent<String>{}//实现不知为何种类型时可以这样定义class Child2<T> implements Parent<T>{}

泛型通配符

package CollectionDemo;import java.util.ArrayList;import java.util.Collection;import java.util.List;public class Demo {public static void main(String[] args) {List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(2);list.add(3);//下面这行代码编译不通过new Demo().getData(list);}public  void getData(Collection<Object> data) {System.out.println(data);}}

看上面的代码,getData中对集合限定了为Object类型,而list为Integer类型,所以编译不通过。此时可以通过将List<Integer> list = new ArrayList<Integer>();中的<Integer>去掉,或者将

getData(Collection<Object> data)改为getData(Objectdata),当然,也可以使用泛型通配符来解决。

将getData(Collection<Object> data)改为getData(Collection<?>data)

可以对类型进行限定范围

? extends E :接收E类型或者E类型的子类型

? super E :接收E类型或者E的福类型

接收Number类型或者Number的子类型

正确: List<? extends Number> x=new List<Integer>();

错误: List<? extends Number> x=newList<String>();

接收Integer或者Integer的父类型

正确:List<? super Integer> x=new List<Number>();

错误:List<? super Integer> x=newList<Byte>();

注:通过泛型,可以将原来程序运行时可能发生的问题,转变为编译时的问题,提高了程序的可读性和稳定性。泛型是提供给编译器使用的,用于限定集合的输入类型,让代码在编译过程中就把错误暴露出来。当编译器编译完带有泛型的程序后,生成的class文件中将不再带有泛型信息,来使程序运行效率不受影响,这个过程称为“擦除”。

0 0
原创粉丝点击