一:简单工厂 最初学习的一个运用简单工厂的例子是做一个计算器: 首先是接口
public interface Cal {
public double Calcu(double num1,double num2);
}
然后是加减乘除类实现计算接口:
public class Add implements Cal{
@Override
public double Calcu(double num1, double num2) {
return num1+num2;
}
}
再写一个工厂类,里面有一个静态方法,原本传的参数是char类型的 + - * /然后再根据传入的参数来选择返回加减乘除的其中一个类,如:
public static Cal choice(char pra){
switch (pra) {
case ‘+‘: return new Add();
case ‘-‘: return new Sub();
default: return null;
}
}
现在运用反射原理,我们可以运用一个更简单的方式:
public static Cal choice(Class clazz) throws InstantiationException, IllegalAccessException{
return (Cal) clazz.newInstance();
}
然后是测试:
//反射工厂
@Test
public void testFactory() throws InstantiationException, IllegalAccessException{
Cal cal=Factory.choice(Add.class);
System.out.println(cal.Calcu(10, 20));
}
二:运用反射原理从数据库里读出数据直接封装到实体集合里 我们首先得有一个跟数据库相对应的实体类,它的属性和数据库字段最好一一对应,如: 我有一个User类,只有id,age,name字段,那么:
public List getList(String sql,Class clazz) throws SQLException, InstantiationException, IllegalAccessException, SecurityException,NoSuchFieldException{
List list=new ArrayList();
PreparedStatement ps=con.prepareStatement(sql);
ResultSet rs=ps.executeQuery();
while(rs.next()){
Object obj=clazz.newInstance();//传进来类的实例
for (int i = 1; i <=rs.getMetaData().getColumnCount(); i++) {//因为rs.get从1开始,rs.getMetaData().getColumnCount()是表头的列数 //clazz.getDeclaredField();得到类的所有字段包括私有的
Field field=clazz.getDeclaredField(rs.getMetaData().getColumnName(i));
field.setAccessible(true);//这个方法设置访问标识,让不能访问的成员可以访问。
field.set(obj, rs.getObject(i));//第一个参数是类型,第二个参数是值
}
list.add(obj);
}
return list;
}
//用反射封装读取数据库的实体类集合
@Test
public void getData() throws SecurityException, SQLException, InstantiationException, IllegalAccessException, NoSuchFieldException{
String sql="select id,age,name from [user]";
List list=getList(sql,User.class);
for (User user : list) {
p(user.getName()+"\t"+user.getAge());
}
}
我数据库里User表里有许多东西,实力类需要什么就读什么,如果实体类的属性跟数据库里的字段不一致的话,比如实力类是Id,数据库里是User_id,这时可以更改sql查询语句来解决这个问题,比如"select id as User_id"。 因为很多时候要用到实体类集合,用这一个方法就可以封装任何实体类,方便许多! ***************************************************************************************************************************另外反射还可以做许多:
//只有带参数的构造函数实例化
@Test
public void shiLiHuaAddPara() throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Class clas=User.class;
Constructor[] cons=clas.getConstructors();
for (Constructor constructor : cons) {
System.out.println(constructor);
}
User user=(User) cons[0].newInstance(10,20,"哈哈");
p(user.getAge());
}
//反射获取父类
@Test
public void getFather() throws ClassNotFoundException{
Class user=Class.forName("cn.zzz.reflect.User");
p(user.getSuperclass().getName());
}
//反射获取接口
@Test
public void getJieKou() throws ClassNotFoundException, SecurityException, NoSuchMethodException{
Class user=Class.forName("cn.zzz.reflect.User");
Class[] clazz=user.getInterfaces();
for (Class class1 : clazz) {
p(class1.getName());
p(class1.getMethod("show"));
}
}
//反射调用字段
@Test
public void getFilds() throws ClassNotFoundException, SecurityException, NoSuchFieldException, InstantiationException, IllegalAccessException{
Class user=Class.forName("cn.zzz.reflect.User");
//这是获取公有字段
//Field[] fields=user.getFields();
//这是获取所有字段
Field[] fields=user.getDeclaredFields();
for (Field field : fields) {
p(field.getName());
}
Field fil=user.getField("id");
Object obj=user.newInstance();
fil.set(obj, 10); p(fil.get(obj));
}
//反射调用方法
@Test
public void getMethods() throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException{
Class user=Class.forName("cn.zzz.reflect.User");
Method[] methods=user.getMethods();
// for (Method method : methods) {
// p(method.getName());
// }
Method method=user.getMethod("setAge",int.class);
Object obj=user.newInstance();
method.invoke(obj, 20);
method=user.getMethod("getAge");
Object ob=method.invoke(obj);
p(ob);
}
public void p(Object obj){
System.out.println(obj.toString());
}