## 1.为什么需要泛型?

JDK提供了ArrayList,可以看作“可变长度”的数组:

  • 比数组使用方便

    示例1:如果使用ArrayList存储String类型:
  • 需要强制转型
  • 不方便,易出错
  1. //演示代码
  2. public class ArrayList1{
  3. private Object[] array;
  4. public void add(Object e){...}
  5. public void remove(int index){...}
  6. public Object get(int index){...}
  7. }
  8. public class Main {
  9. public static void main(String[] args){
  10. ArrayList1 list = new ArrayList1();
  11. list.add("hello");
  12. String one = (String) list.get(0);//需要强制转型
  13. list.add(new Integer(123));//加入Integer类型,提示Error : ClassCastException
  14. String second = (String) list.get(1);
  15. }
  16. }

示例2: 为了解决示例1中的问题,为String单独编写一种ArrayList:

  • 不需要强制转型
  • 编译器强制检查放入的类型
  1. public class ArrayList1{
  2. private String[] array;
  3. public void add(String e){}
  4. public void remove(int index){}
  5. public String get(int index){return array[index];}
  6. }
  7. public class Main {
  8. public static void main(String[] args){
  9. ArrayList1 list = new ArrayList1();
  10. list.add("hello");
  11. String one = list.get(0);//不再需要强制转型
  12. list.add(new Integer(123));//IDE就会提示编译错误,不需要等到编译时
  13. String second = (String) list.get(1);
  14. }
  15. }

新的问题:还需要为其他所有从class单独编写一种ArrayList:Long, Double, Person, Integer。

必须把ArrayList变成一种模版.

1.1范型就是定义一种模版,例如ArrayList

  • 在代码中为用到的类创建对应的ArrayList<类型>

    * ArrayList strList = new ArrayList();
  • 编译器针对类型做检查

    * strList.add("hello");

    * strList.add(new Integer(123));//compile error
  1. public class ArrayList1<T> {
  2. private T[] array;
  3. public void add(T e){}
  4. public void remove(int index){}
  5. public T get(int index){return array[index];}
  6. }
  7. public class Main {
  8. public static void main(String[] args){
  9. ArrayList1<String> strList = new ArrayList1<String>();
  10. ArrayList1<Integer> inList = new ArrayList1<Integer>();
  11. ArrayList1<Float> flList = new ArrayList1<Float>();
  12. }
  13. }

2.泛型的继承关系

  1. ArrayList1<T>实现了List<T>接口,ArrayList1<T>可以向上转型为List<T>.
  1. //示例代码,忽略错误
  2. public class ArrayList1<T> implements List<T> {
  3. private T[] array;
  4. public void add(T e){}
  5. public void remove(int index){}
  6. public T get(int index){return array[index];}
  7. //List<T>的方法...
  8. }
  9. public class Main {
  10. public static void main(String[] args){
  11. ArrayList1<String> strList = new ArrayList1<String>();
  12. List<String> list = new ArrayList<String>();
  13. }
  14. }
  1. 不能把ArrayList1<Integer>向上转型为ArrayList1<Numberr>或List<Number>
  2. ArrayList1<Integer>和ArrayList1<Number>两者没有继承关系。
  3. Number包含float的子类,ArrayList1<Integer>不接受float
  1. import java.util.ArrayList;
  2. //使用JDK的ArrayList<t>
  3. public class Main {
  4. public static void main(String[] args){
  5. ArrayList<String> strList = new ArrayList<String>();
  6. strList.add("abc");
  7. strList.add("xyz");
  8. //strList.add(new Integer(123));
  9. String first = strList.get(0);
  10. System.out.println(first);
  11. }
  12. }

3.总结:

  • 泛型就是编写模版代码来适应任意类型
  • 不必对类型进行强制转换
  • 编译器将对类型进行检查
  • 注意泛型的继承关系:
  1. * 可以把ArrayList<Integer>向上转型为List<Integer> T不能变)
  2. * 不能ArrayList<Integer>向上转型为ArrayList<Number>

廖雪峰Java4反射与范型-3范型-1什么是泛型的更多相关文章

  1. 廖雪峰Java4反射与泛型-3范型-4擦拭法

    1.擦拭法是Java泛型的实现方式. 编译器把类型视为Object. * 泛型代码编译的时候,编译器实际上把所有的泛型类型T统一视为Object类型.换句话说,虚拟机对泛型一无所知,所有的工作都是编译 ...

  2. 廖雪峰Java4反射与泛型-3范型-3编写泛型

    编写泛型类比普通的类要麻烦,而且很少编写泛型类. 1.编写一个泛型类: 按照某种类型(例如String)编写类 标记所有的特定类型例如String 把特定类型替换为T,并申明 Pair.java pa ...

  3. 廖雪峰Java4反射与泛型-3范型-6super通配符

    1.super通配符 1.1super通配符第一种用法 泛型的继承关系 Pair<Integer>不是Pair<Number>的子类,如 static void set(Pai ...

  4. 廖雪峰Java4反射与泛型-3范型-5extends通配符

    1.泛型的继承关系: Pair<Integer>不是Pair<Number>的子类 add()不接受Pair<Integer> Pair.java package ...

  5. 廖雪峰Java4反射与泛型-3泛型-7泛型和反射

    1.部分反射API是泛型 1.1获取反射API的泛型 部分反射API是泛型,如Class<T>是泛型 //如果使用Class,不带泛型,出现compile warning编译警告 Clas ...

  6. 廖雪峰Java4反射与泛型-2注解-3处理注解

    1.处理注解 注解本身对对代码逻辑没有任何影响 SOURCE类型的注解在编译期就被丢掉了 CLASS类型的注解仅保存在class文件中 RUNTIME类型的注解在运行期可以被读取 如何使用注解由工具决 ...

  7. 廖雪峰Java4反射与泛型-1反射-2访问字段Field和3调用方法Method

    2.字段Field 2.1.通过Class实例获取字段field信息: getField(name): 获取某个public的field,包括父类 getDeclaredField(name): 获取 ...

  8. 廖雪峰Java4反射与泛型-1反射-1Class类

    1.Class类与反射定义 Class类本身是一种数据类型(Type),class/interface的数据类型是Class,JVM为每个加载的class创建了唯一的Class实例. Class实例包 ...

  9. 廖雪峰Java4反射与泛型-2注解-2定义注解

    1.定义注解 使用@interface定义注解Annotation 注解的参数类似无参数方法 可以设定一个默认值(推荐) 把最常用的参数命名为value(推荐) 2.元注解 2.1Target使用方式 ...

随机推荐

  1. [codeforces][Educational Codeforces Round 53 (Rated for Div. 2)D. Berland Fair]

    http://codeforces.com/problemset/problem/1073/D 题目大意:有n个物品(n<2e5)围成一个圈,你有t(t<1e18)元,每次经过物品i,如果 ...

  2. 《DSP using MATLAB》Problem 5.2

    代码: %% ---------------------------------------------------------------------------------- %% Output ...

  3. Go Example--打点器

    package main import ( "time" "fmt" ) func main() { // 定时器 是当你想要在未来某一刻执行一次时使用的 - ...

  4. 用Python开发Zeroc Ice应用

    Zeroc Ice简介   Zeroc ICE(Internet Communications Engine ,互联网通信引擎)是目前功能比较强大和完善的RPC框架,支持跨平台.跨语言调用.它非常灵活 ...

  5. Singer 学习十一 配置以及状态管理

    配置和状态文件通过提供身份验证信息,开始时间和有关以前调用的信息,帮助为Taps和Targets提供上下文 配置文件 配置文件包含tap 运行需要的信息,通常包含API,以及数据源的凭据 特殊字段 s ...

  6. ElasticSearch:Lucene和ElasticSearch

    Lucene的概念: 关于索引 索引(index)和搜索(搜索),在lucene以及es里面索引是一个动作,即插入动作,包括创建索引以及为索引添加文档:所有则是针对索引(添加)的文档按照评分规则进行查 ...

  7. Android Monkey测试入门

    第一步:搭建环境:主要是安装和搭建java和sdk环境,说白了,对我们安卓开发来说,只要搭建好了Android开发环境,Monkey测试环境基本就是OK的了.可以参考:http://www.cnblo ...

  8. deque/defaultdict/orderedict/collections.namedtuple()/collections.ChainMap() 笔记

    关于deque的使用 collections.deque([list[, max_length]]) # 不限定长度,可随意添加没有上限 >>> from collections i ...

  9. Centos 7 systemctl和防火墙firewalld命令

    今天自己在Hyper-v下搭建三台Linux服务器集群,用于学习ELKstack(即大数据日志解决技术栈Elasticsearch,Logstash,Kibana的简称),下载的Linux版本为cen ...

  10. Excel技巧--使用规划求解

    当我们需要求在有限预算下可以购买的商品数量时,我们就可以使用“规划求解”功能.如上图,在1000元的预算目标内,我们能购买左图中的各书籍多少本.而这些数量,就可以使用“规划求解”来获取答案. 1.实际 ...