Java中的泛型(Generic)

╰+哭是因爲堅強的太久メ 2022-06-17 09:28 361阅读 0赞

一、泛型作用

  1. * JDK5中的泛形允许程序员在编写集合代码时,就限制集合的处理类型,从而把原来程序运行时可能发生问题,转变为编译时的问题,以此提高程序的可读性和稳定性(尤其在大型程序中更为突出)。
  2. * 注意:泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛形的java程序后,生成的class文件中将不再带有泛形信息,以此使程序运行效率不受到影响,这个过程称之为“擦除”。
  3. * 泛形的基本术语,以ArrayList<E>为例:<>念着typeof
  4. *
  5. * ArrayList<E>中的E称为类型参数变量
  6. * ArrayList<Integer>中的Integer称为实际类型参数 整个称为
  7. * ArrayList<E>泛型类型
  8. * 整个ArrayList<Integer>称为参数化的类型ParameterizedType

二、泛型的典型应用

  1. * 使用迭代器迭代泛型集合中的元素。
  2. * 使用增强for循环迭代泛型集合中的元素。
  3. * 存储HashMap中的元素
  4. * SSH框架中抽取Service层代码
  5. * 使用泛型的几个常见问题:
  6. *
  7. * 使用泛型时,泛型类型必须为引用类型,不能是基本数据类型。
  8. * ArrayList<String> list = new ArrayList<Object>();
  9. * ArrayList<Object> list = new ArrayList<String>();
  10. * ArrayList<String> list = new ArrayList ();
  11. * ArrayList list = new ArrayList<String>();

三、自定义泛型——泛型方法

  1. * Java程序中的普通方法、构造方法和静态方法都可以使用泛型。方法使用泛型前,必须对泛型进行声明,语法:<T>,T可以是任意字幕,但通常必须要大写。<T>通常需放在方法的返回值声明之前。例如:public static <T> void doxx(T t);
  2. * 注意:
  3. *
  4. * 只有对象类型才能作为泛型方法的实际参数。
  5. * 在泛型中可以同时有多个类型,例如:public static <K,V> V getValue(K key) { return map.get(key);}
  6. * 泛型类和反射泛型
  7. *
  8. * 如果一个类多处都要用到同一个泛型,这时可以把泛型定义在类上(即类级别的泛型),语法格式如下:
  9. public class GenericDao<T> {
  10. private T field1;
  11. public void save(T obj){}
  12. public T getId(int id){}
  13. }
  14. * 注意,静态方法不能使用类定义的泛型。而应单独定义泛型。
  15. * 泛型的典型应用:BaseDao和反射泛型
  16. public BaseDao(){
  17. Type type=this.getClass().getGenericsuperclass();
  18. ParamterizedType pt=(ParamterizedType )type;
  19. clazz=pt.getActualTypeArgyments()[0];
  20. }

四、泛型的高级应用——通配符
* 定义一个方法,接收一个集合,并打印出集合中的所有元素,如下所示:

  1. void print (Collection<String> c) {
  2. for (String e : c) {
  3. System.out.println(e);
  4. } }
  5. * 问题:该方法只能打印保存了Object对象的集合,不能打印其它集合。通配符用于解决此类问题,方法的定义可改写为如下形式:
  6. void print (Collection<?> c) {   
  7. //Collection<?>(发音为:"collection of unknown")
  8. for (Object e : c) {
  9. System.out.println(e);
  10. }
  11. }
  12. * 此种形式下需要注意的是:由于print方法c参数的类型为Collection<?>,即表示一种不确定的类型,因此在方法体内不能调用与类型相关的方法,例如add()方法。
  13. * 总结:使用?通配符主要用于引用对象,使用了?通配符,就只能调对象与类型无关的方法,不能调用对象与类型有关的方法。

五、泛型的高级应用——有限制的通配符
* 限定通配符的上边界:只可读取,不可以存取

  1. 正确:Vector<? extends Number> x = new Vector<Integer>();
  2. 错误:Vector<? extends Number> x = new Vector<String>();
  3. * 限定通配符的下边界:只能存取不能读取
  4. 正确:Vector<? super Integer> x = new Vector<Number>();
  5. 错误:Vector<? super Integer> x = new Vector<Byte>();

注意:
1、对象实例化时不指定泛型,默认是object
2、泛型不同的引用不能互相赋值。
3、加入集合中的对象类型必须与指定的泛型类型一致。
4、静态方法中不能使用类的泛型
5、如果泛型类是一个接口或者抽象类,则不可创建泛型类的对象。
6、不能在catch中使用泛型
7、从泛型类派生子类,泛型类需要具体化。

泛型与继承的关系:
1、A类是B类的子类,G是带泛型声明的类或接口,那么G<A>不是G<B>的子类。

通配符:
A类是B类的子类,G是带泛型声明的类或接口,则G<?>是G<A>,G<B>的父类。
1、以List<?>为例,能读取其中的数据,因为不管存储的是什么类型的元素,其一定是Object类或者其子类。
2、以List<?>为例,不可以向其中写入数据,因为没有指明可以存放到其中的元素的类型!。唯一例外的是:null。

发表评论

表情:
评论列表 (有 0 条评论,361人围观)

还没有评论,来说两句吧...

相关阅读

    相关 (Generic) 优点

    泛型引入前编程的痛点 `JDK 1.5` 版本以前没有泛型,使用 Object 来实现不同类型的处理,有两个缺点 1、每次使用时都需要`强制转换`; 2、在`编译

    相关 【Reflect】(generics)

    Java泛型概述     泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。 这种参数类型可以用在类、接口和方法的创