java反射的作用与原理
对于任何一个类在运行时都可以通过反射知道这个类的所有方法和属性。对于任意一个对象,都能够调用他的方法。在java中只要知道一个类的名字就能够得到这个类的所有信息,这种动态调用方法和动态创建对象的方式叫做反射。
反射中获取Class对象的几种实现方式
1.对象.getClass();
Class studentClass = student.getClass();
2.Class.forName("类路径”);
Class studentClass = Class.forName("com.learn.pojo.Student");
3.类名.class
Class studentClass = Student.class;
案例:利用反射创建对象实例并进行参数赋值
/**
* 反射创建对象实例赋值
* @param objectName 类地址
* @param mapData 参数
* @return 对象实例
*/
public Object reflexTest(String objectName, Map<String,Object> mapData) throws Exception {
//获取到对象Class
Class<?> studentClass = Class.forName(objectName);
//创建无参实例
Object object=studentClass.newInstance();
//获取到所有public参数
Field[] fields = studentClass.getFields();
for(int i=0;i<fields.length;i++){
Field field=fields[i];
//根据参数名称获取到map中的数据
Object fieldValue=mapData.get(field.getName());
if(null!=mapData.get(field.getName())){
//共有参数直接赋值
field.set(object,fieldValue);
}
}
//获取到所有私有参数
Field[] declaredFields = studentClass.getDeclaredFields();
for(int i=0;i<declaredFields.length;i++){
Field field=declaredFields[i];
//赋予反射对象超级权限,绕过语言权限检查,获取到私有信息
field.setAccessible(true);
//私有参数名称
String declaredFieldName=field.getName();
//获取参数set方法名字
String setMethodName="set"+declaredFieldName.substring(0,1).toUpperCase()+declaredFieldName.substring(1,declaredFieldName.length());
//获取参数类型
Class<?> type = field.getType();
//根据参数名称获取到map中的数据
Object fieldValue=mapData.get(declaredFieldName);
if(null!=fieldValue){
//数据类型与参数类型不同就跳过
if(mapData.get(declaredFieldName).getClass()!=type) {
break;
}
//获取到对应参数的set方法
Method setMethod = studentClass.getMethod(setMethodName,type);
//反射调用,这里是set方法给参数赋值
setMethod.invoke(object,fieldValue);
}
}
return object;
}
main方法调用
public static void main(String[] args) throws Exception {
Test3 t3=new Test3();
Map<String,Object> map=new HashMap<>();
map.put("name","李明");
map.put("age",12);
map.put("like","read book");
map.put("money",1.5d);
Object student = t3.reflexTest("com.learn.pojo.Student", map);
System.out.println(student.toString());
Map<String,Object> tMap=new HashMap<>();
tMap.put("name","王老师");
tMap.put("age",40);
Object teacher = t3.reflexTest("com.learn.pojo.Teacher", tMap);
System.out.println(teacher.toString());
}
Class表示正在运行的java程序类或者接口,所有通过反射获取对象信息都要通过Class类来实现。
Field提供有关类或者接口的参数信息,以及参数访问权限控制。
Method提供有关类和接口的方法信息,以及方法访问权限控制。
Constructor提供有关类的构造函数的信息,以及构造函数的访问权限控制。
反射机制的优缺点:
1.能够在程序运行时动态的获取类的实例,提高了代码的灵活性。
2.使用反射机制效率较低,因为需要解析字节码,将内存中的对象提取出来进行解析。可以通过setAccessible(true)方法关闭JDK的安全检查来提升反射速度。
3.多次创建同一个类的实例时,有缓存速度会快很多。
4.相对不安全,破坏了类的封装新,因为可以访问到类的私有信息。