java之泛型
来源:互联网 发布:网络红人马浩东前女友 编辑:程序博客网 时间:2024/05/17 03:23
概述
泛型是JDK1.5以后才有的, 可以在编译时期进行类型检查,且可以避免频繁类型转化!
// 集合的声明 不使用泛型List list = new ArrayList();list.add("evan_qb");list.add(1);// 集合的使用 当不使用泛型时,会抛出运行时异常String str = (String) list.get(1);// 使用泛型// 声明泛型集合的时候指定元素的类型 使用泛型后,当存储不同类型时,编译时期就会报错List<String> list = new ArrayList<String>();list.add("China");//list.add(1);// 编译时期报错String str = list.get(1);
在运行时抛异常,和在编译时报错,显然,在编译时报错更容易定位错误
而且使用泛型也易于维护,不再鱼龙混杂,而是存储相同类型,易于维护,可以让你消除代码中的强制类型转换,同时获得一个附加的类型检查层,该检查层可以防止有人将错误类型的键或值保存在集合中。
泛型擦除
泛型只在编译时期有效,编译后的字节码文件中不存在有泛型信息!
泛型擦除实例
public void save(List<Person> p){}public void save(List<Dept> d){ // 报错: 与上面方法编译后一样}
泛型写法
正确写法:
List<Object> list = new ArrayList<Object>();List<String> list1 = new ArrayList<String>();List list2 = new ArrayList<String>();
错误写法:
//泛型类型要一致List<Object> list4 = new ArrayList<String>();// 泛型类型必须是引用类型,不能为基本类型List<int> list5 = new ArrayList<int>();
泛型方法/泛型类/泛型接口
泛型方法:
// 定义泛型方法public <K,T> T save(T t,K k) { return null;}// 使用泛型方法: 在使用泛型方法的时候,确定泛型类型save(1.0f, 1);
泛型类:
public class GenericDemo<T> {// 定义泛型方法public <K> T save(T t,K k) {return null;}}// 泛型类: 在创建爱泛型类对象的时候,确定类型GenericDemo<String> demo = new GenericDemo<String>();
泛型接口:
//定义泛型接口public interface IBaseDao<T> {void save(T t );void update(T t );}
泛型接口类型确定:
实现泛型接口的类也是抽象,那么类型在具体的实现中确定或创建泛型类的时候确定
public class BaseDao<T> implements IBaseDao<T> {}
在业务实现类中直接确定接口的类型
public class PersonDao implements IBaseDao<Person>{}
泛型关键字:
在泛型中:
? 指定只是接收值
extends 元素的类型必须继承自指定的类
super 元素的类型必须是指定的类的父类
关键字 ?
//只带泛型特征的方法public void save(List<?> list) {// 只能获取、迭代list; 不能编辑list}// ? 可以接收任何泛型集合, 但是不能编辑集合值; 所以一般在方法参数中用List<?> list = new ArrayList<String>();//list.add("");// 报错
关键字: extends【上限】
list集合只能处理 Double/Float/Integer等类型
限定元素范围:元素的类型要继承自Number类 (上限)
public void save(List<? extends Number> list) {}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); //报错
关键字 : super【下限】
super限定元素范围:必须是父类(Object)或者本身(String)【下限】
public void save(List<? super String> list) {}// 调用上面方法,必须传入String的父类List<Object> list1 = new ArrayList<Object>();List<String> list2 = new ArrayList<String>();List<Integer> list3 = new ArrayList<Integer>();save(list3); //报错
泛型的反射
Type 接口,任何类型默认的接口!
包括: 引用类型、原始类型、参数化类型
List<String> list = new ArrayList<String>();
泛型集合: list
集合元素定义:new ArrayList<String>(); 中的String
参数化类型: ParameterizedType
即:“ArrayList<String>” 为参数化类型
泛型反射的案例:通用的jdbc方法
我们使用一个通用的BaseDao方法去存储基本的jdbc方法
由于本案例使用的数据库时Oracle数据库,还有DBUtil组件,所以需要导入相应的包
下面先写BaseDao类
public class BaseDao<T> {private Class clazz;private String tableName;/** * 构造函数: * 1. 获取当前运行类的参数化类型; * 2. 获取参数化类型中实际类型的定义(class) */public BaseDao(){// this 表示当前运行类 (AccountDao/StudentDao)// this.getClass() 当前运行类的字节码(AccountDao.class/StudentDao.class)// this.getClass().getGenericSuperclass(); 当前运行类的父类,即为BaseDao<Account>// ParameterizedType,其实就是“参数化类型”//获取当前运行类的父类,Type类型表示任意类型Type type = this.getClass().getGenericSuperclass();//强制转换为ParameterizedType(参数化)类型ParameterizedType pt = (ParameterizedType) type;// 获取参数化类型中类似【new Type[]{Account.class}】,获取实际的参数类型Type[] types = pt.getActualTypeArguments();//获取数据的第一个元素:Account.classclazz = (Class) types[0];//获取表名tableName = clazz.getSimpleName();}public T findById(int id){Connection conn = null;String sql = "select * from " + tableName + " where id = ?";try {conn = ConnectionFactory.getConnection();System.out.println(tableName);QueryRunner qr = new QueryRunner();return qr.query(conn,sql, new BeanHandler<T>(clazz),id);} catch (SQLException e) {throw new RuntimeException(e);}finally{ConnectionFactory.close(conn, null, null, null);}}/** * 获取所有 * @return */public List<T> getAll(){Connection conn = null;String sql = "select * from " + tableName;try {conn = ConnectionFactory.getConnection();return new QueryRunner().query(conn, sql,new BeanListHandler<T>(clazz));} catch (SQLException e) {throw new RuntimeException(e);}finally{ConnectionFactory.close(conn, null, null, null);}}}
当谁需要用到这些方法时,我们就将其继承BaseDao,然后我们可以通过反射泛型的技术,或者正在运行的类的类型,然后进行相应的CRUD操作,而每个子类只需要定义特有的jdbc的方法就行了
分别编写Account类和Student类继承BaseDao类
public class AccountDao extends BaseDao<Account>{}public class StudentDao extends BaseDao<Student>{}
Student实体类
public class Student {private int id;private String stuName;private double money;//省略getter和setter方法构造方法toString()方法}
Account实体类
public class Account {private int id;private String accountName;private double money;//省略getter和setter方法构造方法toString()方法}
对应的创建表的语句:
create sequence account_seq increment by 1 start with 1;create sequence stu_seq increment by 1 start with 1;create table account( id number(10), accountName varchar2(20), money number(10,2));create table Student( id number(10), stuName varchar2(20), money number(10,2));drop table student;-- 插入数据到account表中insert into account values(account_seq.nextval,'张三',1000.00);insert into account values(account_seq.nextval,'李四',2000.00);--插入数据到Student表中insert into student values(stu_seq.nextval,'evan_qb',500.00);insert into student values(stu_seq.nextval,'李四',1000.00);commit
然后我们就来测试一波
StudentDao stuDao = new StudentDao();List<Student> stus = stuDao.getAll();for (Student stu : stus) {System.out.println(stu);
运行结果如下:
AccountDao account = new AccountDao();Account account1 = account.findById(1);//List<Account> accounts = account.getAll();System.out.println(account1);
运行结果如下:
这样,我们就用反射泛型实现了对jdbc的优化
- java之泛型
- java之泛型
- Java 之泛型
- Java之泛型
- java之泛型
- Java之泛型
- Java之泛型
- JAVA之泛型
- Java之泛型
- Java之泛型
- java之泛型
- Java之泛型
- Java之泛型
- java之泛型
- Java之泛型
- java之泛型
- java之泛型
- java基础-Java之泛型
- 自定义拖动View
- shell的判断结构
- 机智云发布机智云5.0 实现物联网应用协同开发
- C#218课的主要内容
- Ubuntu14.04安装Matlab R2013b
- java之泛型
- bash 中各特殊字符的含义
- java基础语法入门大纲
- 第四周【项目3
- sql中inner jion和left join以及right join之间的区别和联系
- HDU 5137How Many Maos Does the Guanxi Worth
- 【数据结构与算法】二叉树的层序遍历
- shiyanbar-2
- bzoj 2752 [HAOI2012]高速公路(road) 线段树