一、基础增强
1. 课程回顾
XML技术
Servlet/Jsp
数据库
Jdbc技术
JavaWeb增强
过滤器、监听器、文件上传与下载、国际化
学过的组件:
Dom4J/Xpath、DBUtils、C3p0、BeanUtils、log4J…
Struts / Spring / Hibernate
二、泛型
2.1 泛型的基本概念
2.2.1 什么是泛型
泛型是JDK1.5以后才有的, 可以在编译时期进行类型检查,且可以避免频繁类型
转化!
2.2.2 泛型的作用
泛型可以把运行时异常提前至编译时异常。
// 运行时期异常
@Test
public void testGeneric() throws Exception {
// 集合的声明
List list = new ArrayList();
list.add("China");
list.add(1);
// 集合的使用
String str = (String) list.get(1);
}
// 使用泛型
@Test
public void testGeneric2() throws Exception {
// 声明泛型集合的时候指定元素的类型
List<String> list = new ArrayList<String>();
list.add("China");
// list.add(1);// 编译时期报错
String str = list.get(1);
}
2.2.3 泛型擦除
泛型只在编译时期有效,编译后的字节码文件中不存在有泛型信息!·
下面的代码会报错,原因是:泛型编译后会进行擦除。
/*
* 泛型擦除实例
*/
public void save(List<Person> p){
...
}
public void save(List<Dept> d){ // 报错: 与上面方法编译后一样
...
}
2.2 泛型写法
1.泛型必须是引用类型,不是基本类型
2.前后两端泛型必须一致。
3.一端出现泛型即可。
// 泛型写法
@Test
public void testGeneric3() throws Exception {
// 声明泛型集合,集合两端类型必须一致
List<Object> list = new ArrayList<Object>();
List<String> list1 = new ArrayList<String>();
List list2 = new ArrayList<String>();
List<Integer> list3 = new ArrayList();
// 错误
//List<Object> list4 = new ArrayList<String>();
// 错误: 泛型类型必须是引用类型,不能为基本类型
List<int> list5 = new ArrayList<int>();
}
2.3 泛型的分类
2.3.1 泛型方法
泛型方法:
1.泛型的声明是在方法上。
2.泛型是在调用泛型方法时创建的。
public class GenericDemo {
// 定义泛型方法
public <T> T save(T t) {
return t;
}
public <T,K> T save(T t,K k) {
return t;
}
// 测试方法
@Test
public void testMethod() throws Exception {
// 使用泛型方法: 在使用泛型方法的时候,确定泛型类型
save(1.0f, 1);
}
}
2.3.2 泛型类
泛型类:
1.泛型的声明是在类上
2.泛型的确立是在创建对象时。
public class GenericDemo<T> {
// 定义泛型方法
public <K> T save(T t,K k) {
return null;
}
public void update(T t) {
}
// 测试方法
@Test
public void testMethod() throws Exception {
// 泛型类: 在创建爱泛型类对象的时候,确定类型
GenericDemo<String> demo = new GenericDemo<String>();
demo.save("test", 1);
}
}
2.3.3 泛型接口
泛型接口:
1.泛型的声明是在接口上
/**
* 泛型接口
*
* @param <T>
*/
public interface IBaseDao<T> {
void save(T t );
void update(T t );
}
2.3.4 泛型类、泛型接口的泛型确立
+++ 泛型类、泛型接口
1)继承泛型类、实现泛型接口时确立泛型
2)继承泛型类、实现泛型接口时延长泛型的生命周期
继承泛型类、实现泛型接口时确立泛型
继承泛型列,确立泛型
public class PersonDao implements IBaseDao<Person>{}
实现泛型接口,确立泛型
public abstract class BaseDao implements IBaseDao<Person> {}
延长泛型时间
继承泛型类,延长泛型的声明周期
public class PersonDao<T> extends BaseDao<t>{}
实现泛型接口,延长泛型的生命首期
public abstract class BaseDao<T> implements IBaseDao<Person> {}
2.4 泛型关键字
泛型中:
? 指定只是接收值
? extends Number 泛型的上线,只能传入Number的子类
? super Number 泛型的下限,只能传入Number的父类
2.4.1 关键字 — ?
public void save(List<?> list) {
// 只能获取、迭代list; 不能编辑list
}
? 只能接受泛型集合,而不能编辑集合值。所以一般在方法参数中用。
如果在方法中使用list.add(..)会报错。
public class App_extends_super {
//只带泛型特征的方法
public void save(List<?> list) {
// 只能获取、迭代list; 不能编辑list
}
@Test
public void testGeneric() throws Exception {
// ? 可以接收任何泛型集合, 但是不能编辑集合值; 所以一般在方法参数中用
List<?> list = new ArrayList<String>();
//list.add("");// 报错
}
}
2.4.2 关键字 — extend 【上限】
public void save(List<? extends Number> list) {
}
泛型的上限:传入的List集合,必须是Number的子类
public class App_extends_super {
/**
* list集合只能处理 Double/Float/Integer等类型
* 限定元素范围:元素的类型要继承自Number类 (上限)
* @param list
*/
public void save(List<? extends Number> list) {
}
@Test
public void testGeneric() throws Exception {
List<Double> list_1 = new ArrayList<Double>();
List<Float> list_2 = new ArrayList<Float>();
List<Integer> list_3 = new ArrayList<Integer>();
List<String> list_4 = new ArrayList<String>();
// 调用
save(list_1);
save(list_2);
save(list_3);
//save(list_4);
}
}
2.4.2 关键字 — super 【下限】
public void save(List<? super String> list) {
}
传入的List集合,必须是String的父类
/**
* 泛型, 涉及到一些关键字
*
* Ctrl + shift + R 查看当前项目中类
* Ctrl + shift + T 查看源码jar包中的类
*
*/
public class App_super {
/**
* super限定元素范围:必须是String父类 【下限】
* @param list
*/
public void save(List<? super String> list) {
}
@Test
public void testGeneric() throws Exception {
// 调用上面方法,必须传入String的父类
List<Object> list1 = new ArrayList<Object>();
List<String> list2 = new ArrayList<String>();
List<Integer> list3 = new ArrayList<Integer>();
//save(list3);
}
}
三、泛型的反射(获取泛型参数化类型)
public class B extends A<Admin>{
@Test
public void test1() {
Class clazz=B.class;
//返回直接父类对象(带有泛型参数化类型)
Type type = clazz.getGenericSuperclass();
ParameterizedType param=(ParameterizedType) type;
//获取参数化类型
Type[] types = param.getActualTypeArguments();
Class t=(Class) types[0];
System.out.println(t.getSimpleName()); //Admin
}
}