转载

聊聊对Java泛型的理解

欢迎关注公众号【 Ccww笔记 】,原创技术文章第一时间推出

一、概念和原理

概念:泛型就是类型参数化,处理的数据类型不是固定的,而是可以作为参数传入。

原理:Java有Java编译器和Java虚拟机,编译器将Java源代码转换为.class文件,虚拟机加载并运行.class文件。对于泛型类,Java编译器会将泛型代码转换为普通的非泛型代码,将类型参数T擦除,替换为Object,插入必要的强制类型转换。

Java虚拟机实际执行的时候,它是不知道泛型这回事的,它只知道普通的类及代码。再强调一下,Java泛型是通过擦除实现的,类定义中的类型参数如T会被替换为Object,在程序运行过程中,不知道泛型的实际类型参数,认识到这一点是非常重要的,它有助于我们理解Java泛型的很多限制。

二、正确使用泛型

2.1、参数化类型和原始类型的兼容性

参数化类型可以引用原始类型的对象,实例:

Collection<String> c = new ArrayList();

原始类型可以应用参数化类型的对象

Collection c = new ArrayList<String>();

参数化类型不考虑类型参数间的继承关系  

ArrayList<String> a = new ArrayList<Object>();

//错误:x:

ArrayList<Object> a = new ArrayList<String>();

//错误:x:

泛型只是在编译期间编译器做类型检查的机制。

ArrayList a1 = new ArrayList<Integer>();

ArrayList<Object> a = a1;

ArrayList a1 = new ArrayList<Integer>();

ArrayList<String> a = a1;

2.2、泛型的约束和局限性

  • 不能使用基本类型实例化类型参数  

  • 不能抛出也不能捕获泛型类实例  

  • 泛型类的静态上下文中类型变量无效,不能在静态域或方法中应用类型变量。 

三、自定义泛型

3.1、自定义泛型类

class GeneDemo<T,U> {

void method1(T t1){

System.out.println(t1);

}

T method2(T t1){

System.out.println(t1)

}

U method(T t1, U u1){

return;

}

}

3.2、自定义泛型方法

放置泛型的类型参数的尖括号应紧邻返回值之前。普通方法、构造方法和静态方法中都可以使用泛型。

当一个变量被声明为泛型时,只能被实例变量、方法和内部类调用,而不能被静态变量和静态方法调用。

因为静态成员是被所有参数化的类所共享的,所以静态成员不应该有类级别的类型参数。若使用需要是静态泛型方法,则重新声明泛型参数。

public class GenericDao<T> {


public void save(T obj) {

}


public T getById(int id) {

return null;

}


/**

* 静态方法。重新声明T,此处的T与GenericDao<T>的T没有关系。

*/

public static <T> void update(T obj){

}

}

四.补充内容

补充1:泛型类型变量的限制    

使用 < T extends BoundingType > 限定泛型类型。T应该是绑定类型的子类型。T和绑定类型可以是类或接口。一个泛型变量或通配符可以有多个限定。限定类型使用"&"分割。若用一个类做限定,它必须是限定列表中的第一个。

例: <V extends Serializable & Cloneable> void method(){}

限定通配符的上边界

<? extends Number> 用于匹配Number及Number的子类。

正确: Vector<? extends Number> x = new Vector<Integer>();//Integer继承了Number

错误: Vector<? extends Number> x = new Vector<String>();

限定通配符的下边界

<? super Integer> 用于匹配Integer及Integer的父类。

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

错误: Vector<? super Integer> x = new Vector<Byte>();

补充2:泛型通配符  

使用"?"通配符可以引用其他各种参数化的类型,"?"通配符定义的变量主要用作引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。

Collection<?> 可以适配 Collection<Object>Collection<Integer>Collection<String> 等。

各位看官还可以吗?喜欢的话,动动手指点个:heartpulse:,点个关注呗!!谢谢支持!

欢迎关注公众号【 Ccww笔记 】,原创技术文章第一时间推出

聊聊对Java泛型的理解

原文  http://mp.weixin.qq.com/s?__biz=MzU2ODk2NDMwNw==&mid=2247484023&idx=1&sn=de92ed02215d0a82e1880b6912feee10
正文到此结束
Loading...