Java基础-反射

194 阅读3分钟

一.概念:将类的各种组成部分封装为其他对象,这就是反射的机制

  好处:可以在程序的运行过程中,操作这些对象
       可以解偶提高程序的扩展性

二.获取字节码对象(Class对象)

  Class.forName(类全路径): 可以把编译好的class文件加载到内存中,并且返回字节码对象
  类名.class:获得内存中已有的字节码对象
  类对象.getClass():通过对象获得内存中的字节码对象

三.字节码对象的操作

 获取成员变量们
 
 //获取所有public修饰的成员变量对象
 Field [] getFields();
 
 //获取指定名称的public的成员变量对象
 Field getFields(String name);
 
 //获取所有的成员变量对象,不考虑修饰符
 Field [] getDeclareFields();
 
  //获取指定名称的的成员变量对象不考虑修饰符
 Field  getDeclareFields(String name);
 
 //成员变量对象的get和set方法,如果不是public修饰的需要执行忽略权限
 field.setAccessible(true);//忽略权限修饰符(暴力反射)
 field.get(对象);
 field.set(对象,属性);

 获取构造函数们
 //获取所有public修饰的构造方法
 Constructor<?>[] getConstructors();
 
 //根据参数获得public修饰的构造方法
 Constructor<T>[] getConstructor(类<?>...parameterTypes);
 
 //获得所有的构造方法,不考虑修饰符
 Constructor<?>[] getDeclareConstructors();
 
 //根据参数获得构造方法,不考虑修饰符
 Constructor<T>[] getDeclareConstructor(类<?>...parameterTypes);
 
 //创建对象,如果不是public修饰的需要执行忽略权限,如果用无参构造的话直接可以Object.Class.newInstace();
 constructor.setAccessible(true);//忽略权限修饰符(暴力反射)
 Object obj=constructor.newInstace(构造参数1,构造参数2......)
 
 获取成员函数们
 //获取所有public修饰的成员方法,包括Object类的方法
 Method [] getMethods();
 
//获取指定public修饰的成员方法,参数:方法名,属性字段....
 Method [] getMethod(String name,类<?>...parameterTypes);
 
//获取所有成员方法,不考虑修饰符,包括Object类的方法
 Method [] getDeclareMethods();
 
//获取指定的成员方法,不考虑修饰符,参数:方法名,属性字段对象...
 Method [] getDeclareMethod(String name,类<?>...parameterTypes);
 
 //执行方法,如果不是public修饰的需要执行忽略权
 method.setAccessible(true);//忽略权限修饰符(暴力反射)
 method.invoke(类对象,属性......)
 
 //获取方法名
 method.getName();
 
 //获取全路径类名
 String className=Object.class.getName();

四.案列

 写一个"框架"来帮我们执行任意类的对象,并且执行其中的任意方法
 
 
public class ReflectTest {

 public static void main(String[] args) throws Exception {
    // 在不改变任意代码的情况下,可以创建任意类的对象,可以执行任意方法
    //实现:
        //1.配置文件
        //2.反射
    //步骤
        //1.将需要创建的对象的全类名和需要执行的方法定义在配置文件中
        //2.在程序中加载读取配置文件
        //3.使用反射技术加载类文件进内存
        //4.创建对象
        //5.执行方法
    Properties properties = new Properties();
    InputStream ips = ReflectTest.class.getClassLoader().getResourceAsStream("pro.properties");
    properties.load(ips);
    String className = properties.getProperty("className");
    String methodName = properties.getProperty("methodName");
    Class<?> cls = Class.forName(className);
    Object obj = cls.newInstance();
    Method method = cls.getDeclaredMethod(methodName);
    method.setAccessible(true);
    method.invoke(obj);

 }
}