JAVA学习-反射:获取class类对象、构造方法、成员变量、成员方法、运行配置文件指定内容

反射

现实生活中有很多反射的例子,比如医院里面的X射线,西游记里面的照妖镜等,可以看出反射其实具有透视的作用,可以透视一个类,透视一个对象

反射的官方定义:在程序运行的过程中,可以动态的创建对象,并获取对象的基本信息,包括属性、方法等;
在运行时去获取一个类的变量和方法信息,然后通过获取到的信息来创建对象,调用方法的一种机制

获取class类的对象

要通过反射去使用一个类,要先获得类型为Class类型的对象
在这里插入图片描述

反射获取构造方法-Constructor

//先获取类的反射对象
        Class<?> c1 = Class.forName("streamliu.student");
//获取反射的构造方法
        Constructor<?> con1 = c1.getConstructor(String.class, int.class, String.class);
        //创建反射的对象
        Object o1 = con1.newInstance("sss", 22, "ds");
        System.out.println(o1);

        Constructor<?> decon = c1.getDeclaredConstructor(String.class);
        //对于访问有限制的对象,用setAccessible值为true时,会取消访问检查
        decon.setAccessible(true);
        Object obj2 = decon.newInstance("dds");
        System.out.println(obj2);

反射获取成员变量-Field

在这里插入图片描述

//先获取类的反射对象
        Class<?> c1 = Class.forName("streamliu.student");
        获取反射的所有成员方法
        
        Field[] fields = c1.getDeclaredFields();
        for(Field field : fields){
    
    
            System.out.println(field);
        }
//获取反射的构造方法
        Constructor<?> con = c1.getConstructor();
               //创建反射的对象
        Object obj = con.newInstance();
        System.out.println(obj);
//反射获取成员变量
        Field namefield = c1.getField("name");
        //访问非public的成员变量
        namefield.setAccessible(true);
        //给成员变量赋值
        namefield.set(obj,"haah");
        Field agefield = c1.getField("age");
        agefield.set(obj,10);
        Field locationfield = c1.getField("location");
        locationfield.set(obj,"shanghai");
        //打印输出成员变量值
        System.out.println(namefield.get(obj));
        System.out.println(agefield.get(obj));
        System.out.println(locationfield.get(obj));

反射获取成员方法-Mehtod

//获取反射的所有的public成员方法
 Method[] methods = c1.getMethods();
 //获取反射的所有包括private的成员方法
        Method[] declaredMethods = c1.getDeclaredMethods();
        for(Method method:declaredMethods){
    
    
            System.out.println(method);
        }
        //获取反射的指定名称的成员方法
        Method m1 = c1.getMethod("method1");
        //反射调用成员方法
        m1.invoke(obj);
        Method[] methods = c1.getMethods();
        Method[] declaredMethods = c1.getDeclaredMethods();
        for(Method method:declaredMethods){
    
    
            System.out.println(method);
        }
       //带参数的成员方法
        Method m2 = c1.getMethod("method2", String.class);
        m2.invoke(obj,"yoyo");

        Method m3 = c1.getMethod("method3", String.class, int.class);
        //对象接收带返回值的参数并打印
        Object obj3 = m3.invoke(obj, "yoyo", 30);
        System.out.println(obj3);
//private修饰的成员方法
        Method m4 = c1.getDeclaredMethod("function");
        m4.setAccessible(true);
        m4.invoke(obj);

反射可以越过泛型检查,直接在集合中添加数据

用反射运行配置文件指定内容

//载入配置文件
        Properties prop = new Properties();
        FileReader fr = new FileReader("stream/peizhi.txt");
        prop.load(fr);
        fr.close();
        //配置文件内容
        /*        className=stream/student
        methodName=study*/
        //将载入内容赋值取数,以便后续调用
        //之后只需要修改配置文件,不用涉及源代码就可以调整配置
        String className = prop.getProperty("className");
        String methodName = prop.getProperty("methodName");

        Class<?> c = Class.forName(className);

        Constructor<?> con = c.getConstructor();
        Object obj = con.newInstance();

        Method m = c.getMethod(methodName);
        m.invoke(obj);

猜你喜欢

转载自blog.csdn.net/weixin_52723971/article/details/111686679