java中反射机制用于动态的获取运行时类型识别,也就是所谓的RTTI,当你从网络上获取一段字节码的时候,告知你这是一个对象的实例,比如hibernat中的你需要对以一个对象进行持久化,你如何获取到它的字段,setter,getter,如何将它存入到对应的表中。或者将配置文件中的各种不同属性值加载到运行时对象属性中的,这些将通过反射机制来获取;
比如下例将一个customer对象通过hibernate保存到数据库中;
这是Customer的代码:
public class Customer{
private int id;
private String name;
public int getId(){
return id;
}
public void setId(int id){
this.id = id;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
我们知道在hibernate用session.save的时候,通过具体的配置文件,将在数据库中找到一张名为Customer的表,并且自动的将id属性和name属性存入到数据库中,那么,jvm是如何确定和Customer表名一致的类就是该Customer.class呢?这就是反射机制的作用了,下面是一个简单问题的实现:
import java.lang.reflect.*;
public class ReflectTest{
public void methodOfReflect(Object o) throws Exception{
Class className = o.getClass();//用于获取该对象的类型信息
Field[] fields = className.getDeclaredFields();//获取该对象的所有字段名
for(int i=0;i<fields.length;i++){
Field field = fields[i];
String name = field.getName();
String firstLetter = name.substring(0,1).toUpperCase();
String getMethodName = "get"+firstLetter+name.substring(1);
String setMethodName = "set"+firstLetter+name.substring(1);
/* 通过字符串拼接获取到field对应的getter,setter */
Method getMethod = className.getMethod(getMethodName,new Class[]{});
Method setMethod = className.getMethod(setMethodName,field.getType());
/* 在对象o上面调用getter方法 */
Object value = getMethod.invoke(o,new Object[]{});
valueArray[i] = value;
System.out.println(name+":"+value);
}
}
public static void main(String args[]){
Customer c = new Customer(10,"JiJi");
ReflectTest rt = new ReflectTest();
rt.methodOfReflect(c);
}
}
上面在获取对应getter和setter的时候会产生类型转换警告,不知道怎么回事,下面的代码清单列出了利用反射机制将对象持久化进数据库,也就是类似于hiberate中的session.save(c):
//Customer.java
public class Customer{
private int id;
private String name;
public Customer(int id,String name){
this.id = id;
this.name = name;
}
public int getId(){
return id;
}
public void setId(int id){
this.id = id;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
//ReflectTest.java
import java.lang.reflect.*;
public class ReflectTest{
private Object[] valueArray;
public Object[] methodOfReflect(Object o) throws Exception{
Class className = o.getClass();
Field[] fields = className.getDeclaredFields();
valueArray = new Object[fields.length];
for(int i=0;i<fields.length;i++){
Field field = fields[i];
String name = field.getName();
String firstLetter = name.substring(0,1).toUpperCase();
String getMethodName = "get"+firstLetter+name.substring(1);
String setMethodName = "set"+firstLetter+name.substring(1);
Method getMethod = className.getMethod(getMethodName,new Class[]{});
Method setMethod = className.getMethod(setMethodName,field.getType());
Object value = getMethod.invoke(o,new Object[]{});
valueArray[i] = value;
}
return valueArray;
}
}
//Persistence.java
import java.lang.reflect.*;
import java.sql.*;
public class Persistence{
public static void main(String arg[]) throws Exception{
Customer c = new Customer(10,"JiJi");
ReflectTest rt = new ReflectTest();
Object[] array = rt.methodOfReflect(c);
String sql = "insert into "+c.getClass().getName()+"(id,name) "+"values(";
for(int i=0;i<array.length;i++){
if(i == array.length-1)
{sql += "'"+array[i].toString()+"'"+")";}
else{sql +="'"+array[i].toString()+"'"+",";}
}
Class.forName("com.mysql.jdbc.Driver");
COnnection conn = DriverManager.getConnction(url,usr,pwd);
Statement stat = conn.getStatement();
ResultSet rs = stat.executeUpdate(sql);
}
}
我觉得吧,如果反射机制结合着具体的应用比较好理解,而不是单独去看文档,可能是我实力不够吧。。