什么是反射机制?
在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。
常用反射机制的场景
反射机制可以在runtime阶段动态地获取所需要用到的类的属性、构造方法、成员方法(获取Class类的实例)
一些编码需求在source阶段是无法实现的,如果正常编码方式可以解决的,强行使用反射反而是毫无意义的
获取Class类的实例的四种方式:
class ReflectionTest{
@Test
public void test1(){
//方式一:调用运行时类的属性:.class
Class clazz1 = Role.class;
//方式二:通过运行时类的对象
Role p1 = new Role();
Class clazz2 = p1.getClass();
//方式三:调用Class的静态方法:forName(String classPath)
Class clazz3 = Class.forName("com.self.反射.Role");
//方式四:使用类的加载器:ClassLoader
ClassLoader classLoader = ReflectionTest.class.getClassLoader();
Class clazz4 = classLoader.loadClass("com.self.反射.Role");
}
}
代码:
例:
被访问的类Role:
public class Role {
private int roleId ;
private String roleName ;
private Role() {}
private Role(int roleId,String roleName) {
this.roleId = roleId ;
this.roleName = roleName ;
}
public int getRoleId() {
return roleId;
}
public void setRoleId(int roleId) {
this.roleId = roleId;
}
private String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
}
获取Role类的构造器、以及它的方法
public class test {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//获取类
Class clazz = Role.class;
//一.获取无参构造器
Constructor cons = clazz.getDeclaredConstructor();
//将获取的构造器的权限改为可访问的
cons.setAccessible(true);
Role r1 = (Role) cons.newInstance();//用无参的构造器创建对象
r1.setRoleId(123);
System.out.println(r1.getRoleId());
//二.获取有参构造器
Constructor cons1 = clazz.getDeclaredConstructor(new Class[]{int.class,String.class});
//
cons1.setAccessible(true);
Role r2 = (Role) cons1.newInstance(new Object[]{1,"张三"});
// System.out.println(""+r2.getRoleId()+r2.getRoleName());
//三.获取方法
Method mtget = clazz.getDeclaredMethod("getRoleName", null);
mtget.setAccessible(true);
Object objresult = mtget.invoke(r2, args);
System.out.println(objresult);
//获取有参方法
Method mt1 = clazz.getDeclaredMethod("setRoleName", new Class[] {String.class});
System.out.println(mt1.invoke(r2, new Object[] {"张三改名了"}));
System.out.println(mtget.invoke(r2, args));
}
}