1.什么是java反射机制
反射机制就是在运行的状态中,对于任意的一个类,都能知道这个类的方法和属性
2.java反射机制类
java.lang.Class//类
java.lang.reflect.Constructor//构造方法
java.lang.reflect.Field //类的成员变量
java.lang.reflect.Method //类的方法
java.lang.reflect.Modifier//访问权限
3.java反射机制实现
class对象的获取
//第一种方式 通过getClass方法
Person person=new Person();
Class
package com.zjm;
public class Person {
private Long id;
private String name;
private String address;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
/**
* 内部类的获取 getDeclaredConstructs()
* @author lenovo
*
*/
public class desss{
}
/**
* getField[] 获取public的属性
*/
public String des;
public Person(Long id, String name, String address) {
super();
this.id = id;
this.name = name;
this.address = address;
}
public Person() {
super();
// TODO Auto-generated constructor stub
}
private Person(String name){
this.name=name;
}
}
Test.java 测试类
package com.zjm;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
//第一种方式 通过getClass方法
Person person=new Person();
Class<?> c =person.getClass();
//第二种方式通过类的class属性
c=Person.class;
//第三种 通过Class类的静态方法 forName()来实现
try {
Class<?> c1=c.forName("com.zjm.Person");
//判断是否是集合
boolean isArray=c1.isArray();
System.out.println("判断是否是集合"+isArray);
boolean isPrimitive = c1.isPrimitive();//判断是否是基础类
System.out.println("判断是否是基础类"+isPrimitive);
boolean isAnnotation=c1.isAnnotation();//判断是否是注解类
System.out.println("判断是否是注解类"+isAnnotation);
boolean isInterface= c1.isInterface();//判断是否是接口类
System.out.println("判断是否是接口类"+isInterface);
boolean isEnum=c1.isEnum();//判断是否是枚举
System.out.println("判断是否是枚举类"+isEnum);
boolean isAnonymousClass= c1.isAnonymousClass();//判断是否是内部类
System.out.println("判断是否是内部类"+isAnonymousClass);
boolean isAnnotationPresent= c1.isAnnotationPresent(Deprecated.class);//判断是否被某个注解修饰
System.out.println("判断是否被某个注解修饰"+isAnnotationPresent);
String className=c1.getName();//获取class名称 包含包名
System.out.println("获取class名称 包含包名:\t"+className);
Package packageInfo=c1.getPackage();//获取class的包的信息
System.out.println("获取class的包的信息:\t"+packageInfo);
String simpleName=c1.getSimpleName();//获取class类名
System.out.println("获取class类名:\t"+simpleName);
int modifiers=c1.getModifiers();//获取class访问权限
System.out.println("获取class访问权限:\t"+modifiers);
System.out.println("--------------------------------");
Class<?>[] declaredClasses=c1.getDeclaredClasses();//内部类
System.out.println("内部类的个数:\t"+declaredClasses.length);
Class<?> declaringClass=c1.getDeclaringClass();//外部类
System.out.println("外部类:\t"+declaringClass);
//获取class对象的属性和方法,构造函数
System.out.println("--------------------------------");
Field[] allFields =c.getDeclaredFields();//获取calss对象的所有属性
for (int i = 0; i < allFields.length; i++) {
System.out.println("获取class对象的所有属性"+allFields[i].getName());
}
System.out.println("----------------------------------");
Field[] desField=c.getFields();//获取class对象的public属性
for (int i = 0; i < desField.length; i++) {
System.out.println("获取class对象的所有属性"+desField[i].getName());
}
System.out.println("----------------------------------------");
//获取所有的构造函数
Constructor<?>[] allconstructors=c1.getDeclaredConstructors();
for (int i = 0; i < allconstructors.length; i++) {
System.out.println("获取指定的构造函数"+allconstructors[i]);
}
System.out.println("--------------------------------------");
//获取指定的声明public的构造函数
Constructor<?>[] constructors=c1.getConstructors();
for (Constructor<?> constructor : constructors) {
System.out.println("获取指定public声明的函数:"+constructor);
}
System.out.println("-----------------------------------");
//class 对象的动态生成
//第一种方式.Class对象用newInstance()方法生成
Object obj=c1.newInstance();
System.out.println(obj);
//第二种方式 对象获得对应Constructor对象。再通过改Constructor对象的newInstance()方法生成
Constructor<?> constructor =c1.getDeclaredConstructor(new Class[]{String.class});
obj=constructor.newInstance(new Object[]{"zjm"});
System.out.println(obj);
System.out.println("---------------------------------");
//动态调用对象
Object obj1 =c1.newInstance();
boolean isInstanceOf=obj1 instanceof Person;
System.out.println("判断是否是Person的子类"+isInstanceOf);
Method method=c.getDeclaredMethod("setName", new Class[]{String.class});
//调用指定的函数并且传递参数
method.invoke(obj1, "张三");
method=c.getDeclaredMethod("getName");
Object result=method.invoke(obj1, new Class[]{});
System.out.println(result);
System.out.println("-------------------------------------");
//通过反射机制获取泛型类型
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
根据上面所了解,我们看一下应用
首先建立一个PERSON类
package com.zjm;
public class PERSON {
private Long ID;
private String NAME;
private String ADDRESS;
public Long getID() {
return ID;
}
public void setID(Long iD) {
ID = iD;
}
public String getNAME() {
return NAME;
}
public void setNAME(String nAME) {
NAME = nAME;
}
public String getADDRESS() {
return ADDRESS;
}
public void setADDRESS(String aDDRESS) {
ADDRESS = aDDRESS;
}
}
连接数据库类
package com.zjm;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.naming.NamingException;
public class DBConnection {
public static Connection getConnection() throws NamingException,SQLException{
try {
Class.forName("oracle.jdbc.OracleDriver");
return DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl","employee","a123");
} catch (ClassNotFoundException e) {
e.printStackTrace();
throw new SQLException("未找到驱动oracle.jdbc.OracleDriver");
}
}
public static void freeConnection(PreparedStatement pstmt, ResultSet rs) {
try {
freeConnection(rs);
freeConnection(pstmt);
} catch (Exception ex) {
}
}
public static void freeConnection(Statement stmt) {
try {
if (stmt != null)
stmt.close();
} catch (SQLException ex) {
}
}
public static void freeConnection(ResultSet rs) {
try {
if (rs != null)
rs.close();
} catch (SQLException ex) {
}
}
}
在进行类的动态反射Common.java
package com.zjm;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class Common {
private Object getMyObject(Object object, ResultSet rs,boolean showlogFlg,boolean withPublicField) {
String fieldName = null;
Object o = null;
try {
//对象的获取
Class obj = Class.forName(object.getClass().getName());
//System.out.println("name"+object.getClass().getName());
//获取class对象
o = obj.newInstance();
//获取class对象所有的字段
Field[] field = obj.getDeclaredFields();
for (Field f : field) {
//截取类型例如:f.getType()是java.lang.String
String type = f.getType().toString().substring(
f.getType().toString().lastIndexOf(".") + 1);
//获取类class类型包括包名
fieldName = f.getName();
try {
//获取class的访问权限 类名是访问权限1字段public 2是private权限 (只对于属性而言) protected权限访问是4 默认没有修饰符的是0
//System.out.println(f.getModifiers());
if (f.getModifiers() == 2||(withPublicField&&f.getModifiers() == 1)) {
//获取class类型的方法
Method[] method = obj.getDeclaredMethods();
for (Method m : method) {
if (m.getName().equalsIgnoreCase(
"set" + f.getName())) {
Object rsValue = null;
if ("String".equals(type)) {
rsValue = rs.getString(fieldName==null?"":fieldName);
} else if ("Long".equalsIgnoreCase(type)) {
rsValue = rs.getLong(fieldName);
} else if ("int".equals(type)) {
rsValue = rs.getInt(fieldName);
} else if ("Integer".equals(type)) {
rsValue = rs.getInt(fieldName);
} else if ("Date".equals(type)) {
rsValue = rs.getDate(fieldName);
} else if ("Double".equalsIgnoreCase(type)) {
rsValue = rs.getDouble(fieldName);
} else if ("Time".equalsIgnoreCase(type)) {
rsValue = rs.getTime(fieldName);
} else if ("Timestamp".equalsIgnoreCase(type)) {
rsValue = rs.getTimestamp(fieldName);
} else if ("BigDecimal".equalsIgnoreCase(type)) {
rsValue = rs.getBigDecimal(fieldName);
} else if ("Boolean".equalsIgnoreCase(type)) {
rsValue = "1".equals(rs
.getString(fieldName)) ? true
: false;
}
try {
//调用invoke函数传值
m.invoke(o, rsValue);
} catch (Exception e) {
System.out.println("查询操作异常:当前实体类中不存在字段:"
+ fieldName + "[" + e.getMessage()
+ "]");
continue;
}
}
}
}
} catch (Exception e) {
if(showlogFlg){
System.out.println("组装对象异常, " + fieldName + "字段和表中的该字段名称或者其类型不能匹配:"
+ e.getMessage());
}
}
}
} catch (Exception e) {
System.out.println("组装对象异常,POJO中的" + fieldName + "字段和表中的该字段名称或者其类型不能匹配:"
+ e.getMessage());
}
return o;
}
public static List query(Connection conn, Object object, String sql) {
List list = new ArrayList();
ResultSet rs = null;
PreparedStatement pstm = null;
try {
pstm = conn.prepareStatement(sql);
rs = pstm.executeQuery();
while (rs.next()) {
Object o = new Common().getMyObject(object, rs,true,false);
list.add(o);
}
} catch (Exception e) {
System.out.println("/查询操作异常!SQL:" + sql);
} finally {
DBConnection.freeConnection(pstm, rs);
}
return list;
}
}
Test.java类
package com.zjm;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;
public class Test {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
try {
conn=DBConnection.getConnection();
String sql="select * from PERSON";
List<PERSON> list=Common.query(conn,new PERSON(), sql);
for (PERSON person : list) {
System.out.println("id:"+person.getID()+"\t"+"name:"+person.getNAME()+"\t"+"address:"+person.getADDRESS());
}
} catch (Exception e) {
e.printStackTrace();
}finally{
DBConnection.freeConnection(ps, rs);
}
}
}
结果:
测试成功。
注意:上面的数据字段要和数据库字段保持一致,只要一个驱动包就能搞定了ojdbc6.jar
反射的应用场景很多很多框架都是用java反射做的,例如:hibernate ,struct2。像保存,删除,更新,自己可以按照上面的例子弄一下