背景:
公司需要开发一个树形结构的界面,点击每个叶子节点都对应一个子界面,然后子界面显示部分参数和一个执行按钮,点击执行按钮,程序会根据叶子节点ID,去数据库捞取配置的类路径,通过反射类路径来执行特定的类方法。
反射也可以用来判断注解和获取注解的值,例如:阿巴阿巴
反射参考代码:
public Object invokeMethod(String classStr,Map param) throws Exception {
try {
// 通过字符串的类来反射
Class clazz = Class.forName(classStr);
// 通过反射获取类的方法【run:方法名,map:run方法的参数】
Method method = clazz.getDeclaredMethod("run",Map.class);
// 调用run方法
return method.invoke(SpringUtil.getBean(clazz),param);
} catch (InvocationTargetException e) {
e.printStackTrace(); //打印错误日志
} catch (Exception e){
throw new RuntimeException(e.getMessage());
}
return null;
}
一、反射机制概念
反射是指在程序运行状态中,对于任意一个类都能够得到这个类所有的属性和方法,并且对于任意一个对象,都能够调用它的任意方法。简单来说:将Java对象的各个部分通过类加载器,封装为成员变量对象、构造方法对象和成员方法对象,并通过反射来动态获取以及调用。
二、反射应用场景
1、源代码阶段
1)用法:Class clazz=Class.forName("类的全路径");
2)作用:多用于配置文件,将类名定义在配置文件中,读取文件内容,加载程序类;
2、Class类对象阶段
1)用法:类名.class,通过类名的属性class获取;
2)作用:多用于参数的传递;
3、运行时阶段
1)用法:对象.getClass();getClass()方法在object类中定义着;
2)作用:多用于对象获取字节码的方式
注意:同一个字节码文件(*.class)在一次程序运行中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个。
三、Class对象功能
1、获取成员变量
public Field getField(String name) //获取类中public的成员变量 public Field[] getFields() // 获取类中所有的public的成员变量 public Field getDeclaredField(String name) //可以获取类中private的成员变量 public Field[] getDeclaredFields() //获取类中所有成员信息 |
2、获取构造方法
package com.dgs.entity;
public class User {
private String username ;
private String password ;
public String age ;
public String sex ;
public User() {
}
public User(String username, String password, String age, String sex) {
this.username = username;
this.password = password;
this.age = age;
this.sex = sex;
}
private User(String username, String password) {
this.username = username;
this.password = password;
}
private User(String username, String password, String age) {
this.username = username;
this.password = password;
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
package com.dgs.main;
import com.dgs.entity.User;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class TestMain {
public static void main(String[] args) throws Exception {
Class userClass = User.class;
Constructor constructor1 = userClass.getConstructor();
System.out.println(constructor1);
Constructor constructor2 = userClass.getConstructor(String.class, String.class, String.class, String.class);
System.out.println(constructor2);
Constructor[] constructors = userClass.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
Constructor declaredConstructor1 = userClass.getDeclaredConstructor(String.class, String.class);
System.out.println(declaredConstructor1);
Constructor[] declaredConstructors = userClass.getDeclaredConstructors();
for (Constructor declaredConstructor : declaredConstructors) {
System.out.println(declaredConstructor);
}
}
}
3、获取成员方法
package com.dgs.main;
import com.dgs.entity.User;
import java.lang.reflect.Method;
public class TestMain {
public static void main(String[] args) throws Exception {
User user = new User();
Class userClass = user.getClass();
Method getSex = userClass.getMethod("getSex");
System.out.println(getSex);
Method[] methods = userClass.getMethods();
for (Method method : methods) {
System.out.println(method);
}
Method setSex = userClass.getDeclaredMethod("setSex",String.class);
System.out.println(setSex);
Method[] declaredMethods = userClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
System.out.println(declaredMethod);
}
}
}
4、具体使用
package com.dgs.main;
import com.dgs.entity.User;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TestMain {
public static void main(String[] args) throws Exception {
User user = new User();
Class userClass = user.getClass();
Constructor constructor = userClass.getConstructor(String.class, String.class, String.class, String.class);
Object userObject = constructor.newInstance("dgs", "1234", "22", "男");
System.out.println(userObject);
Method setSex = userClass.getMethod("setSex", String.class);
setSex.invoke(userObject, "女");
System.out.println(userObject);
Field username = userClass.getDeclaredField("username");
username.setAccessible(true);
username.set(userObject,"dgj");
System.out.println(userObject);
}
}
Field成员变量
操作:
①设置值 void set(Object obj,Object value)
②获取值 get(Object obj)
③忽略访问权限修饰符的安全检查setAccessible(true)
Constructor:构造方法
创建对象:
①T newInstance(Object... initargets)
②:如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance
Method:方法对象
执行方法:Object invoke(Object obj,Object... args)