https://segmentfault.com/a/1190000014120746
泛型:把类型明确的工作推迟到创建对象或调用方法之后,简单来说,你有一个类,在使用时内部类型暂不确定,给使用给一个占位符给代替,在使用的时候可以给确定其定义的类型。例如HashMap等集合类中就用到了泛型:
ArrayList<String> stringValues=new ArrayList<String>();
有了泛型以后:
- 代码更加简洁【不用强制转换】
- 程序更加健壮【只要编译时期没有警告,那么运行时期就不会出现ClassCastException异常】
- 可读性和稳定性【在编写集合的时候,就限定了类型】
泛型底层如何实现?
Java的泛型是使用类型擦除来实现的,意味着当你在使用泛型时,任何具体的类型信息都被擦除了,你唯一知道的就是你在使用一个对象。
泛型用于编译阶段,编译后的字节码文件不包含泛型类型信息,因为虚拟机没有泛型类型对象,所有对象都属于普通类。例如定义 List<Object>
或 List<String>
,在编译后都会变成 List
。
定义一个泛型类型,会自动提供一个对应原始类型,类型变量会被擦除。如果没有限定类型就会替换为 Object,如果有限定类型就会替换为第一个限定类型,例如 <T extends A & B>
会使用 A 类型替换 T。
ava语言的泛型采用的是擦除法实现的伪泛型,泛型信息(类型变量、参数化类型)编译之后通通被除掉了。使用擦除法的好处就是实现简单、非常容易Backport,运行期也能够节省一些类型所占的内存空间。而擦除法的坏处就是,通过这种机制实现的泛型远不如真泛型灵活和强大。Java选取这种方法是一种折中,因为Java最开始的版本是不支持泛型的,为了兼容以前的库而不得不使用擦除法。