JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。
Java反射的主要功能:
1、 确定一个对象的类;
2、 取出类的modifiers,数据成员,方法,构造器,和超类;
3、 找出某个接口里定义的常量和方法说明;
4、 创建一个类实例,这个实例在运行时刻才有名字(运行时间才生成的对象);
5、 取得和设定对象数据成员的值,如果数据成员名是运行时刻确定的也能做到;
6、 在运行时刻调用动态对象的方法;
7、 创建数组,数组大小和类型在运行时刻才确定,也能更改数组成员的值.
没有使用反射机制的Dao实现类
public class IndentDaoImpl implements IndentDao {
private Connection con = null;
private PreparedStatement ps = null;
private ResultSet rs = null;
//原始的写法
public List<Indentinquire> selectPerson(int IndentID) {
String sql="select * from Best_Indent where Best_Indent.IndentID=?";
List<Indentinquire> list = new ArrayList<Indentinquire>();
Indentinquire users = null;
try {
con = DbUtil.getConnection();
ps = con.prepareStatement(sql);
ps.setInt(1, IndentID);
rs = ps.executeQuery();
while (rs.next()) {
users=new Indentinquire();
users.setAdult(rs.getInt("Adult"));
users.setBaby(rs.getInt("Baby"));
users.setChildren(rs.getInt("Children"));
users.setAirBus(AirBus);
users.setCabinClass(CabinClass);
users.setFlightdateone(FlightDate);
users.setDepartC(DepartC);
users.setReachCity(ReachCity);
list.add(users);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
DbUtil.close(con, ps, rs);
}
return list;
}
}
那么在Java中又是如何使用反射机制的呢?使用反射机制又有何好处呢?为什么要使用反射机制呢?这些问题都是你们产生的困惑吧。第一,使用反射机制可以减少代码来,从而提高代码的高效性。第二,Java中反射是在运行中动态的加载进入。有个很大的好处就是可以节省很多资源,加快运行速度。其实,反射机制的用法也是挺简单的。下面这个是一个封装类,可以直接拷贝代码过去用就行啦!
反射类的封装
package com.gx.util;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 把 ResultSet的结果放到 java对象中
* @author en
* @version 2017.7.11
*/
public class JdbcHelper {
/**
* 把单条数据的ResultSet的结果放到 java对象中
* @param rs ResultSet结果集
* @param obj java类的class
* @return
*/
public static <T>T getSingleResult(ResultSet rs, Class<T> obj) {
//创建实例
T instance=null;
try {
//ResultSetMetaData 有关 ResultSet 中列的名称和类型的信息。
ResultSetMetaData metaData = rs.getMetaData();
//获取总的列数
int count=metaData.getColumnCount();
//遍历ResultSet
while(rs.next())
{
instance=obj.newInstance();
//遍历里面的列
for (int i = 1; i <= count; i++) {
//---获取列名
String name = metaData.getColumnName(i);
// 改变列名格式成 java 命名格式 主要是针对 _ 分割的情况 如user_id
name = toJavaField(name);
//---获取类型
Class<?> type = obj.getDeclaredField(name).getType();
//---获取setter方法
// 首字母大写
String replace = name.substring(0, 1).toUpperCase() + name.substring(1);
Method setMethod = obj.getMethod("set" + replace, type);
//---判断读取数据的类型
if (type.isAssignableFrom(String.class)) {
setMethod.invoke(instance, rs.getString(i));
}
else if (type.isAssignableFrom(int.class)|| type.isAssignableFrom(Integer.class)) {
setMethod.invoke(instance, rs.getInt(i));
}
else if (type.isAssignableFrom(Boolean.class) || type.isAssignableFrom(boolean.class)) {
setMethod.invoke(instance, rs.getBoolean(i));
}
else if (type.isAssignableFrom(Date.class)) {
setMethod.invoke(instance, rs.getDate(i));
}
}
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO: handle exception
}
return instance;
}
/**
* 把多条数据的ResultSet的结果放到 List<T>中
* @param rs ResultSet结果集
* @param obj java类的class
* @return
*/
public static <T> List<T> getResult(ResultSet rs, Class<T> obj) {
try {
List<T> list = new ArrayList<T>();
//ResultSetMetaData 有关 ResultSet 中列的名称和类型的信息。
ResultSetMetaData metaData = rs.getMetaData();
//获取总的列数
int count=metaData.getColumnCount();
//遍历ResultSet
while (rs.next()) {
//---创建对象实例
T instance = obj.newInstance();
for (int i = 1; i <= count; i++) {
//---获取列名
String name = metaData.getColumnName(i);
// 改变列名格式成 java 命名格式 主要是针对 _ 分割的情况 如user_id
name = toJavaField(name);
//---获取类型
Class<?> type = obj.getDeclaredField(name).getType();
//---获取setter方法
// 首字母大写
String replace = name.substring(0, 1).toUpperCase() + name.substring(1);
Method setMethod = obj.getMethod("set" + replace, type);
//---判断读取数据的类型
if (type.isAssignableFrom(String.class)) {
setMethod.invoke(instance, rs.getString(i));
}
else if (type.isAssignableFrom(int.class)|| type.isAssignableFrom(Integer.class)) {
setMethod.invoke(instance, rs.getInt(i));
}
else if (type.isAssignableFrom(Boolean.class) || type.isAssignableFrom(boolean.class)) {
setMethod.invoke(instance, rs.getBoolean(i));
}
else if (type.isAssignableFrom(Date.class)) {
setMethod.invoke(instance, rs.getDate(i));
}
}
list.add(instance);
}
return list;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
/**
* 数据库命名格式转java命名格式
* @param str 数据库字段名
* @return java字段名
*/
public static String toJavaField(String str) {
//主要是针对 _ 分割的情况 如user_id
if (str.indexOf('_') > -1) {
str=str.toLowerCase();
}
String[] split = str.split("_");
StringBuilder builder = new StringBuilder();
builder.append(split[0]);// 拼接第一个字符
// 如果数组不止一个单词
if (split.length > 1) {
for (int i = 1; i < split.length; i++) {
String string = split[i];
// 去掉下划线,首字母变为大写
split[i] = string.substring(0, 1).toUpperCase() + string.substring(1);
builder.append(split[i]);
}
}
return builder.toString();
}
}
使用反射机制的Dao实现类
public class IndentDaoImpl implements IndentDao {
private Connection con = null;
private PreparedStatement ps = null;
private ResultSet rs = null;
public List<Indentinquire> selectPerson(int IndentID) {
String sql="select * from Best_Indent where Best_Indent.IndentID=?";
List<Indentinquire> list = new ArrayList<Indentinquire>();
Indentinquire users = null;
try {
con = DbUtil.getConnection();
ps = con.prepareStatement(sql);
rs = ps.executeQuery();
list=JdbcHelper.getResult(rs, Indentinquire.class);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
DbUtil.close(con, ps, rs);
}
return list;
}
}
值得注意: list=JdbcHelper.getResult(rs, Indentinquire.class) 这其中JdbcHelper这个是上面封装的类,括号中的第二个参数是你要查询数据封装的vo类。JdbcHelper这个类其实可以直接拿去用,不需要再修改。