廖雪峰Java4反射与范型-3范型-1什么是泛型
## 1.为什么需要泛型?
JDK提供了ArrayList,可以看作“可变长度”的数组:
- 比数组使用方便
示例1:如果使用ArrayList存储String类型: - 需要强制转型
- 不方便,易出错
//演示代码
public class ArrayList1{
private Object[] array;
public void add(Object e){...}
public void remove(int index){...}
public Object get(int index){...}
}
public class Main {
public static void main(String[] args){
ArrayList1 list = new ArrayList1();
list.add("hello");
String one = (String) list.get(0);//需要强制转型
list.add(new Integer(123));//加入Integer类型,提示Error : ClassCastException
String second = (String) list.get(1);
}
}
示例2: 为了解决示例1中的问题,为String单独编写一种ArrayList:
- 不需要强制转型
- 编译器强制检查放入的类型
public class ArrayList1{
private String[] array;
public void add(String e){}
public void remove(int index){}
public String get(int index){return array[index];}
}
public class Main {
public static void main(String[] args){
ArrayList1 list = new ArrayList1();
list.add("hello");
String one = list.get(0);//不再需要强制转型
list.add(new Integer(123));//IDE就会提示编译错误,不需要等到编译时
String second = (String) list.get(1);
}
}
新的问题:还需要为其他所有从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
public class ArrayList1<T> {
private T[] array;
public void add(T e){}
public void remove(int index){}
public T get(int index){return array[index];}
}
public class Main {
public static void main(String[] args){
ArrayList1<String> strList = new ArrayList1<String>();
ArrayList1<Integer> inList = new ArrayList1<Integer>();
ArrayList1<Float> flList = new ArrayList1<Float>();
}
}
2.泛型的继承关系
ArrayList1<T>实现了List<T>接口,ArrayList1<T>可以向上转型为List<T>.
//示例代码,忽略错误
public class ArrayList1<T> implements List<T> {
private T[] array;
public void add(T e){}
public void remove(int index){}
public T get(int index){return array[index];}
//List<T>的方法...
}
public class Main {
public static void main(String[] args){
ArrayList1<String> strList = new ArrayList1<String>();
List<String> list = new ArrayList<String>();
}
}
不能把ArrayList1<Integer>向上转型为ArrayList1<Numberr>或List<Number>
ArrayList1<Integer>和ArrayList1<Number>两者没有继承关系。
而Number包含float的子类,ArrayList1<Integer>不接受float。
import java.util.ArrayList;
//使用JDK的ArrayList<t>
public class Main {
public static void main(String[] args){
ArrayList<String> strList = new ArrayList<String>();
strList.add("abc");
strList.add("xyz");
//strList.add(new Integer(123));
String first = strList.get(0);
System.out.println(first);
}
}

3.总结:
- 泛型就是编写模版代码来适应任意类型
- 不必对类型进行强制转换
- 编译器将对类型进行检查
- 注意泛型的继承关系:
* 可以把ArrayList<Integer>向上转型为List<Integer> (T不能变)
* 不能ArrayList<Integer>向上转型为ArrayList<Number>
廖雪峰Java4反射与范型-3范型-1什么是泛型的更多相关文章
- 廖雪峰Java4反射与泛型-3范型-4擦拭法
1.擦拭法是Java泛型的实现方式. 编译器把类型视为Object. * 泛型代码编译的时候,编译器实际上把所有的泛型类型T统一视为Object类型.换句话说,虚拟机对泛型一无所知,所有的工作都是编译 ...
- 廖雪峰Java4反射与泛型-3范型-3编写泛型
编写泛型类比普通的类要麻烦,而且很少编写泛型类. 1.编写一个泛型类: 按照某种类型(例如String)编写类 标记所有的特定类型例如String 把特定类型替换为T,并申明 Pair.java pa ...
- 廖雪峰Java4反射与泛型-3范型-6super通配符
1.super通配符 1.1super通配符第一种用法 泛型的继承关系 Pair<Integer>不是Pair<Number>的子类,如 static void set(Pai ...
- 廖雪峰Java4反射与泛型-3范型-5extends通配符
1.泛型的继承关系: Pair<Integer>不是Pair<Number>的子类 add()不接受Pair<Integer> Pair.java package ...
- 廖雪峰Java4反射与泛型-3泛型-7泛型和反射
1.部分反射API是泛型 1.1获取反射API的泛型 部分反射API是泛型,如Class<T>是泛型 //如果使用Class,不带泛型,出现compile warning编译警告 Clas ...
- 廖雪峰Java4反射与泛型-2注解-3处理注解
1.处理注解 注解本身对对代码逻辑没有任何影响 SOURCE类型的注解在编译期就被丢掉了 CLASS类型的注解仅保存在class文件中 RUNTIME类型的注解在运行期可以被读取 如何使用注解由工具决 ...
- 廖雪峰Java4反射与泛型-1反射-2访问字段Field和3调用方法Method
2.字段Field 2.1.通过Class实例获取字段field信息: getField(name): 获取某个public的field,包括父类 getDeclaredField(name): 获取 ...
- 廖雪峰Java4反射与泛型-1反射-1Class类
1.Class类与反射定义 Class类本身是一种数据类型(Type),class/interface的数据类型是Class,JVM为每个加载的class创建了唯一的Class实例. Class实例包 ...
- 廖雪峰Java4反射与泛型-2注解-2定义注解
1.定义注解 使用@interface定义注解Annotation 注解的参数类似无参数方法 可以设定一个默认值(推荐) 把最常用的参数命名为value(推荐) 2.元注解 2.1Target使用方式 ...
随机推荐
- generator插件配置方式使用
generator插件配置方式使用 <build> <plugins> <plugin> <groupId>org.mybatis.generator& ...
- python django day 2
django-admin.py startproject zqxt_viewscd zqxt_viewspython manage.py startapp calczqxt_views/urls.py ...
- 进程的环境变量environ
编程之路刚刚开始,错误难免,希望大家能够指出. 每个进程都有自己的环境变量,在C语言程序中可使用外部变量(char **environ)来访问环境,而库函数可允许进程去获取或修改自己环境的值. 两种方 ...
- Tag文件的创建与应用
Tag文件,几乎和JSP文件一模一样,可以被JSP页面动态加载调用.Tag文件有什么优势呢(既然和JSP几乎一模一样,那就得想想这个必然有不一样的地方,不然要它存在干嘛) 在设计Web应用时,可以通过 ...
- Mybaits代码生成使用
https://jingyan.baidu.com/album/00a07f3869881082d028dc98.html PS:根据数据库中的表 生成代码
- sqler sql 转rest api redis 接口使用
sqler 支持redis 协议,我们可以用过redis client 连接sqler,他会将宏住转换为redis command 实现上看源码我们发现是基于一个开源的redis 协议的golang ...
- 在sorted range上的操作(includes,set_union,set_intersection,set_difference)
includes //版本一:用operator <比较元素 template <class InputerIterator1,class InputerIterator2> boo ...
- zookeeper 图形化的客户端工具:ZooInspector
查看Zookeeper中的数据,我们可以通过ZkCli.sh命令客户端查看,但是不太直观,因为Zookeeper本身数据是以树型结构存储组织的, 今天推荐一个实用的界面操作工具ZooInspector ...
- create-react-app 搭建的项目中,使用 stylus
相关介绍文章: react学习系列1 修改create-react-app配置支持stylus:https://www.jianshu.com/p/9cd7a0dff11f 在react中使用styl ...
- Linux下Redis开机自启(Centos6)
1.设置redis.conf中daemonize为yes,确保守护进程开启. 查找redis配置文件redis.conf [root@localhost /]# find / -name redis. ...