# 第四章第三节--4 泛型擦拭法
标签(空格分隔): 廖雪峰
---
## java泛型的实现方式--擦拭法
在编译器编译的时候,编译器实际上把所有的泛型类型`T,`统一视为`Object`类型.也就是说虚拟机其实对泛型并不关心.而对泛型的处理过程其实发生在编译阶段.
![编译器的处理过程](http://p0b921qfc.bkt.clouddn.com/18-5-18/98406482.jpg)
上面是原始代码,下面是编译器实际处理的代码.编译器实际上把类型`T`视为`Object`.然后在需要的时候会根据T类型进行安全的强制转移.所以Java的泛型实际上是由编译器在编译的时候进行的,编译器内部永远把所有类型视为`Object`.
## 擦拭法带来的局限.
- `<T>`不能是基本数据类型,例如`int`.
因为在编译器的内部把`T`视为`Object`,而`Object`是无法等于基本数据类型的.
- 无法获取带泛型的`Class`,无法用`==`或者`instanceof`判断是否相等.
![无法获取Class](http://p0b921qfc.bkt.clouddn.com/18-5-18/22136504.jpg)
所有的泛型实例,无论泛型的T是什么。`getClass`返回的`Class`都是同一个`Class`。
- 泛型的方法中不能有和`Object`本身方法重名的方法.
## 泛型的继承
- 继承泛型必须指明泛型参数,而子类中也就只能存放泛型参数中的类型.
![继承](http://p0b921qfc.bkt.clouddn.com/18-5-18/13404178.jpg)
- 可以通过子类获取父类的泛型类型.
![通过子类获取泛型的泛型参数类型](http://p0b921qfc.bkt.clouddn.com/18-5-18/1806342.jpg)
## 小节小结
- Java的泛型采用擦拭法的方式实现.
- 擦拭法决定了泛型<T>:
1. 不能是基本类型,例如int
2. 不能获取待泛型类型的Class,例如`Pair<String>.class`
3. 不能判断带泛型类型的类型,例如: `x instanceof Pair<String>`
4. 不能实例化 T的类型 例如: `new T()`;
5. 泛型方法要防止重复定义方法,例如:`pulic boolean equals(T obj)`
- 子类可以通过获取泛型类型的类型参数T.
- 前言
- 一:Java快速入门
- 二:Java面向对象编程
- 三:Java异常处理
- 错误处理
- Java的异常
- 捕获异常
- 抛出异常
- 自定义异常
- 断言和日志
- 使用断言
- 使用JDK Logging
- 使用Commons Logging
- 使用Log4j
- 四:Java反射与泛型
- 反射
- Class类
- 访问字段
- 调用方法
- 调用构造方法
- 获取继承关系
- 注解
- 使用注解
- 定义注解
- 处理注解
- 泛型
- 什么是泛型
- 使用泛型
- 编写泛型
- 擦拭法
- extends通配符
- super通配符
- 泛型和反射
- 五:Java集合
- Java集合简介
- Java集合简介
- List
- 使用List
- 编写equals方法
- Map
- Set
- Queue
- Stack
- 最佳实践
- 六:Java IO编程
- 七:Java处理日期和时间
- 八:JUnit单元测试
- 九:Java正则表达式
- 十:Java加密与安全
- 十一:Java多线程编程
- 十二:Maven基础
- 十三:Java网络编程
- 十四:Java操作XML和JSON
- 十五:Java JDBC编程
- 十六:Java函数式编程