廖雪峰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使用方式 ...
随机推荐
- Blender 画正四面体
正四面体打开“添加网格”菜单(Shift + A),然后选择“锥形”.将“顶点数”设置为3,将“半径1”保留为默认值1.000,将“半径2”设置为0.000.现在,将深度设置为 {根号2,约等于1.4 ...
- BOM-JavaScript浏览器的对象模型
BOM-JavaScript是运行在浏览器中的,所以提供了一系列对象用于和浏览器窗口进行交互,这些对象主要包括window.document.location.navigator和screen等.通常 ...
- JavaScript 缓存基本原理
// 这是个闭包函数,接收一个函数,可以把接收的函数转换成具有缓存能力的函数 var memoize = function(f) { // 使用一个 cache 对象来进行缓存 var cache = ...
- java super的用法
通过用static来定义方法或成员,从某种程度上可以说它类似于C语言中的全局函数和全局变量. this&super这两个关键字的意义和用法. 在Java中,this通常指当前对象,super则 ...
- jenkins 使用smtp2http 邮件服务,扩展灵活的构建通知功能
smtp2http 是一个很方便的可以将smtp 转换为http 服务的工具,同时也支持扩展的开发,我们可以使用此工具 扩展灵活的ci.cd 生命周期管理,而不是简单的邮件处理 备注: 使用docke ...
- Python_getter和setter方法
当给属性赋值的时候,使用实例.属性=属性值的方式显然把属性暴露出来了,并且也无法对属性值进行限制检查,java中提供了setter和getter方法,那么python是如何做的呢?更多内容请参考:Py ...
- Oracle12C版本安装步骤
一.下载路径 http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html file1,file ...
- adb command
- Quest for sane signals in Qt - step 1 (hand coding a Q_OBJECT)
探索qt的信号ref: http://crazyeddiecpp.blogspot.hk/2011/01/quest-for-sane-signals-in-qt-step-1.html If it ...
- oracle之 单实例监听修改端口
Oracle 单一主机多个实例多个监听器配置要点 1. 一台服务器主机, 有多个实例, 如: TSDB/ORCL; 又需要配置多个监听器 2. 需要指定不同的LISTENER端口 3.pmon ...