二十、反射


一、反射的概述

什么是反射?
发射允许对封装类的字段,方法和构造函数的信息进行编程访问。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、获取class对象的三种方式

在这里插入图片描述

 public static void main(String[] args) throws ClassNotFoundException {
        //1.第一种方式 Class.forName("全类名")
        //全类名 = 包名 + 类名
        Class clazz = Class.forName("myReflect.ReflectDemo1.Student");
        System.out.println(clazz); // class myReflect.ReflectDemo1.Student

        //第二种方式 类名.class
        Class clazz2 = Student.class;
        System.out.println(clazz2); //class myReflect.ReflectDemo1.Student

        //第三种方式 对象.getClass()
        Student s = new Student();
        Class clazz3 = s.getClass();
        System.out.println(clazz3); //class myReflect.ReflectDemo1.Student

    }

三、反射获取构造方法

在这里插入图片描述
在这里插入图片描述

public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        //0.获取class字节码文件对象
        Class clazz = Class.forName("myReflect.ReflectDemo2.Student");

        //获取构造方法
        Constructor[] cons = clazz.getConstructors();
        System.out.println(Arrays.toString(cons));  // [public myReflect.ReflectDemo2.Student(), public myReflect.ReflectDemo2.Student(java.lang.String)]

        Constructor[] dcons = clazz.getDeclaredConstructors();
        System.out.println(Arrays.toString(dcons)); // [public myReflect.ReflectDemo2.Student(), private myReflect.ReflectDemo2.Student(java.lang.String,int), protected myReflect.ReflectDemo2.Student(int), public myReflect.ReflectDemo2.Student(java.lang.String)]

        Constructor con1 = clazz.getDeclaredConstructor();
        System.out.println(con1); // public myReflect.ReflectDemo2.Student()

        Constructor con2 = clazz.getDeclaredConstructor(String.class);
        System.out.println(con2); //public myReflect.ReflectDemo2.Student(java.lang.String)

        Constructor con3 = clazz.getDeclaredConstructor(int.class);
        System.out.println(con3); //protected myReflect.ReflectDemo2.Student(int)

        Constructor con4 = clazz.getDeclaredConstructor(String.class, int.class);
        System.out.println(con4); // private myReflect.ReflectDemo2.Student(java.lang.String,int)

        //获取权限修饰符
        int modifiers = con4.getModifiers();
        System.out.println(modifiers); // 2

		//获取参数信息
        Parameter[] parameters = con4.getParameters();
        System.out.println(Arrays.toString(parameters));

		//获取学生对象
        //暴力反射:临时取消权限校验
        con4.setAccessible(true);
        Student s1 = (Student) con4.newInstance("张三", 23);
        System.out.println(s1);
    }

四、反射获取成员变量

在这里插入图片描述
在这里插入图片描述

public static void main(String[] args) throws Exception {
        //获取class字节码文件对象
        Class clazz = Class.forName("myReflect.ReflectDemo3.Student");

        //获取成员变量
        Field[] f1 = clazz.getFields();
        System.out.println(Arrays.toString(f1)); // [public java.lang.String myReflect.ReflectDemo3.Student.gender]

        Field[] f2 = clazz.getDeclaredFields();
        System.out.println(Arrays.toString(f2)); //[private java.lang.String myReflect.ReflectDemo3.Student.name, private int myReflect.ReflectDemo3.Student.age, public java.lang.String myReflect.ReflectDemo3.Student.gender]

        Field gender = clazz.getField("gender");
        System.out.println(gender);

        Field name = clazz.getDeclaredField("name");
        System.out.println(name);

        //获取权限修饰符
        int modifiers = name.getModifiers();
        System.out.println(modifiers);

        //获取成员变量的名字
        String name1 = name.getName();
        System.out.println(name1);

        //获取成员变量的类型
        Class<?> type = name.getType();
        System.out.println(type);

        //获取成员变量记录的值
        Student s = new Student("zhangsan",23,"男");
        name.setAccessible(true);
        Object value = name.get(s);
        System.out.println(value);

        //修改对象里面记录的值
        name.set(s,"lisi");

        System.out.println(s);
    }

五、反射获取成员方法

在这里插入图片描述
在这里插入图片描述

public static void main(String[] args) throws Exception {
        //获取class字节码文件对象
        Class clazz = Class.forName("myReflect.ReflectDemo4.Student");

        //获取所有的方法对象(包含父类中的方法)
        Method[] methods = clazz.getMethods();
        /*for (Method method : methods) {
            System.out.println(method);
        }*/
        //获取所有的方法对象(不包含父类中的方法,但是可以获取本类中私有的方法)
        Method[] declaredMethods = clazz.getDeclaredMethods();
        /*for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }*/

        //获取单个方法
        Method m = clazz.getDeclaredMethod("eat", String.class);
//        System.out.println(m);

        //获取修饰符
        int modifiers = m.getModifiers();
        System.out.println(modifiers);

        //获取方法的名字
        String name = m.getName();
        System.out.println(name);

        //获取方法的形参
        Parameter[] parameters = m.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }
        //获取方法抛出的异常
        Class<?>[] exceptionTypes = m.getExceptionTypes();
        for (Class<?> exceptionType : exceptionTypes) {
            System.out.println(exceptionType);
        }

        //方法运行
        Student s = new Student();
        m.setAccessible(true);
        //参数一s:表示方法的调用者
        //参数二"烤肠":表示在调用方法时传递的实际参数
        Object result = m.invoke(s, "烤肠");

        //获取方法的返回值
        System.out.println(result);
    }

六、反射的作用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

public static void main(String[] args) throws IllegalAccessException, IOException {
        Student s = new Student("小A", 23, "女", 167.5, "睡觉");
        Teacher t = new Teacher("波妞", 10000);

        saveObject(s);
    }

    //把对象里所有的成员变量名和值保存到文件中
    private static void saveObject(Object obj) throws IllegalAccessException, IOException {
        //获取字节码文件的对线
        Class<?> clazz = obj.getClass();

        //创建IO流
        BufferedWriter bw = new BufferedWriter(new FileWriter("day33_code/a.txt", true));
        //获取所有的成员变量
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            declaredField.setAccessible(true);
            String name = declaredField.getName();
            Object value = declaredField.get(obj);
            bw.write(name+"="+value);
            bw.newLine();
        }
        bw.close();
    }

在这里插入图片描述
在这里插入图片描述

public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //读取配置文件中的信息
        Properties prop = new Properties();
        FileInputStream fis = new FileInputStream("day33_code\\prop.properties");
        prop.load(fis);
//        System.out.println(prop);

        //获取全类名和方法名
        String className = (String) prop.get("classname");
        String methodName = (String) prop.get("method");
//        System.out.println(className);
//        System.out.println(methodName);

        //利用发射创建对象并运行方法
        Class<?> clazz = Class.forName(className);

        //获取构造方法
        Constructor<?> con = clazz.getDeclaredConstructor();
        Object obj = con.newInstance();
        System.out.println(obj);

        //获取成员方法并运行
        Method method = clazz.getDeclaredMethod(methodName);
        method.setAccessible(true);
        method.invoke(obj);
    }

在这里插入图片描述

  • 13
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值