1. 泛型
l 基本用法:
A)概述
泛型可以在编译时进行类型检查,可以避免繁琐的类型转换。
public class App { @Test public void testGeneric2()throws Exception{ List<String> list= new ArrayList<String>(); list.add("sdfasdf"); //list.add(1);编译出错 String str=list.get(1); } } |
l 泛型擦除
泛型只在编译时期有效,编译后的字节码文件中不存在有泛型信息!
l 泛型的写法
1、声明泛型集合,集合两端必须一致;
2、泛型类型必须为应用类型;
l 泛型类/泛型方法/
作用:
设计公用的类、方法,对公用的业务实现进行抽取!
使程序更灵活!
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{ //使用泛型方法:在使用泛型方法的时候,确定泛型类型 //save(1.0f,1); //泛型类 //在创建对象的时候确定泛型类型 GenericDemo<String> demo=new GenericDemo<String>(); demo.save("test", 1); } } |
l 泛型接口
泛型接口: public interface IBaseDao<T> { void save(T t); void update(T t); } |
//具体业务模块的实现传递对象方法 public class BaseDaoimplements IBaseDao<Person> { public void save(Person t) { } public void update(Person t) { } } |
//在穿件类对象的时候确定泛型类型 public class BaseDAO1<T>implements IBaseDao<T>{ public void save(T t) { } public void update(T t) { } } |
public abstract class BaseDao2<T>implements IBaseDao<T> { } |
l 泛型关键字
Ctr+shift_R 查看当前项目中的类
Ctr+shift+T 查看原码jar中的类
Ctr+shift+L 自动生成返回类型
? 指定只是接收值
// ? 可以接收任何泛型集合, 但是不能编辑集合值; 所以一般在方法参数中用
List<?> list = new ArrayList<String>();
//list.add("");// 报错
extends 元素的类型必须继承自指定的类
list集合只能处理 Double/Float/Integer等类型,限定元素范围:元素的类型要继承自Number类
public void save(List<? extends Number> list) {
}
super 元素的类型必须是指定的类的父类
public class App_super { // super限定元素范围:必须是String父类 【下限】 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); } } |
l 反射泛型
案例:设置统统方法,会用反射泛型
步骤:
1、案例分析/案例
2、涉及知识点(jdk api)
3、优化 / 反射
反射涉及的接口:API
Type 所有类型中的公共高级接口;任何类型默认的接口;
包括:引用烈性,原始类型,参数化类型
List<String> list = new ArrayList<String>():
泛型集合:list
集合元素定义:new ArrayList<String>();中的String
参数化类型:ArrayList<String>
import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.sql.SQLException; import org.apache.commons.dbutils.handlers.BeanHandler; public class BaseDao<T> { //保存当前运行类的参数化类型中的实际的类型 private Class clazz; //表名 private String tableName; //构造函数: //1、获取当前运行类的参数化类型 // 2,获取参数化类型中的实际类型 public BaseDao(){ //this 表示单钱运行类 //this.getClass() 当前运行类的字节码文件 // this.getClass().getGenericSuperclass();//当前运行类的父类 //其实就是参数化类型 Type type = this.getClass().getGenericSuperclass(); //强制转化为“参数化类型" 即 [BaseDao<Account>] ParameterizedType pt = (ParameterizedType) type; //获取参数化类型中实际类型的定义 Type types[]=pt.getActualTypeArguments(); //获取数组中的第一个元素 clazz=(Class) types[0]; //表名:与类名一样,就是获得类名 tableName=clazz.getSimpleName(); System.out.println(tableName); } public T findById(int id){ /*1.知道封装的对象类型 2.表名【表名与对象名称一样,且主键都为id】 ---》得到当前运行类集成的父类BaseDao<Account> --->得到Account.class */ String sql ="select * from "+ tableName +" where id=? "; try { return JdbcUtils.getQuerrRunner().query(sql,new BeanHandler<T>(clazz), id); } catch (SQLException e) { throw new RuntimeException(e); } } |
public class AdminDaoextends BaseDao<Admin> {} |
public class AccountDaoextends BaseDao<Account>{} |
import org.junit.Test; public class App { @Test public void testSave()throws Exception{ AdminDao admindao=new AdminDao(); Admin admin=admindao.findById(1); System.out.println(admin); } } |
public List<T> findAll(){ String sql ="select * from "+ tableName ; try { return JdbcUtils.getQuerrRunner().query(sql,new BeanListHandler<T>(clazz)); } catch (SQLException e) { throw new RuntimeException(e); } } |
2. 反射
反射就是可以在运行时期动态的创建对象以及获取对象的属性和方法。
import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method;
import org.junit.Test;
public class App { public void testInfo()throws Exception{ String className="com.bxh.c_reflect.Admin"; Class<?> clazz=Class.forName(className); //创建对象 Admin admin = (Admin) clazz.newInstance(); //Constructor<?> constructor = clazz.getDeclaredConstructor(String.class); //Admin admin=(Admin) constructor.newInstance("jack"); } //获取属性名称、值 @Test public void testField()throws Exception{ String className="com.bxh.c_reflect.Admin"; Class<?> clazz=Class.forName(className); Admin admin=(Admin) clazz.newInstance(); //获取所有属性名称 Field[] fs= clazz.getDeclaredFields(); for (Field f : fs) { //设置强制访问 f.setAccessible(true); //获得属性名 String name=f.getName(); Object value=f.get(admin); System.out.println(name+"="+value); } } //反射获取方法 @Test public void testMethod()throws Exception{ String className="com.bxh.c_reflect.Admin"; Class<?> clazz=Class.forName(className); Admin admin=(Admin) clazz.newInstance(); //获取方法对象、public int getId() Method m = clazz.getDeclaredMethod("getId"); //获取方法返回值 Object r_value=m.invoke(admin); System.out.println(r_value); } } |