Java之反射

  • 类是如何加载的?
  • 1.加载
  • 将类的.class文件加载到方法区
    
  • 创建一个Class对象(表示就是.class文件) 相当于文件的对象
    
  • 2.连接
  • 验证  验证一下类的内部结构(成员变量 和 方法)
    
  • 准备  为静态变量或静态方法开辟空间 赋初始值
    
  • 解析  将局部变量进行替换 替换成对应值
    
  •      int a = 10 下面所有的a直接替换成10
    
  • 3.初始化
  • 创建对象 new对象(堆内存开辟空间 跟之前一样)
    
  • 类是什么时候被加载的?
  • 当使用类的时候,该类一定会被加载
    
  • 加载该类时 会先加载该类的父类
    
  • 类是用什么加载的?
  • 使用类加载器加载类
    
  •      1.根加载器   加载JDK的lib文件夹下的jar文件
    
  •      2.扩展加载器 加载ext文件夹下的文件
    
  •      3.系统加载器 咱们自己的类/导入的jar包
    

反射

可以将一个正在运行的类通过这个Class文件的对象,可以直接获取类内部的所有方法和成员变量。

  • 获取Class文件对象
    1.通过对象获取
    2.通过类获取
    3.通过Class中的静态方法获取(Class.forName())
    比如说我们创建了一个Person类
        // 通过对象获取
        Person person = new Person();
        // 获取Person类的 Class文件对象
        Class<? extends Person> c1 = person.getClass();
        // 全类名
        System.out.println(c1);
        
        // 通过类获取
        Class<Person> c2 = Person.class;
        System.out.println(c2\);
        // 常用(只需一个字符串 就能获取该类的Class对象)
        // 注意参数要填全类名  包名+类名
        Class<?> c3 = Class.forName("xx.Person");
        System.out.println(c3);
  • 通过Class文件对象获取类中构造方法
        Class<?> c = Class.forName("xx.Person");
        // 获取所有public公有的构造方法
        Constructor<?>[] constructors = c.getConstructors();
        // 遍历
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor);
        }
        // 获取单个的构造方法
        Constructor<?> constructor2 = c.getConstructor();
        // 利用该构造方法创建对象
        Object newInstance = constructor2.newInstance();
        
        System.out.println(newInstance);
        // 有参构造创建对象 参数是  参数类的文件类型
        Constructor<?> constructor = c.getConstructor(String.class, int.class);
        Object newInstance2 = constructor.newInstance("hanhan", 29);
        System.out.println(newInstance2);

        /*
         * 通过Class文件对象快速创建对象
         * 前提:
         * 1.类必须用public
         * 2.必须提供无参的构造方法
         * 3.该无参的构造方法必须是public
         */
        // 快速创建对象(直接使用类中的无参构造方法创建)
        Object object = c.newInstance();
        System.out.println(object);
        
        
        
        // 获取类中所有的构造方法(包括私有)
        Constructor<?>[] constructors = c.getDeclaredConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor);
        }
        // 获取私有的构造方法
        Constructor<?> constructor = c.getDeclaredConstructor(int.class, String.class);
        // 打开私有方法使用的权限
        constructor.setAccessible(true);
        Person newInstance = (Person)constructor.newInstance(12, "HANHAN");
        System.out.println(newInstance);
        
        
        // 获取所有成员变量(公开的)
        Field[] fields = c.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        // 单独获取指定的成员变量
        Field field = c.getField("name");
        System.out.println(field);
        // 通过反射给这个属性赋值
        field.set(object, "憨憨");
        System.out.println(object);
        
        
        // 获取私有成员变量并打印
        Field field2 = c.getDeclaredField("age");
        field2.setAccessible(true);
        field2.set(object, 14);
        System.out.println(object);
  • 获取成员方法
        Class<?> c = Class.forName("XX.Person");
        // 获取类中所有的公开方法(包括父类的)
        Method[] methods = c.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        // 获取指定的成员方法
        /*
         * 参数1.获取的属性的名字
         * 参数2.获取方法的参数的Class类型
         * 
         */
        Method method = c.getMethod("eat");
        System.out.println(method);
        Object object = c.newInstance();
        // 调用方法
        /*
         * 参数1.调用该方法的对象
         * 参数2.调用该方法 要传入的参数
         */
        Object invoke = method.invoke(object);
        System.out.println(invoke);
        
        
        
        Method method2 = c.getMethod("speak", String.class);
        Object invoke2 = method2.invoke(object, "English");
        System.out.println(invoke2);
        
        Method declaredMethod = c.getDeclaredMethod("play", String.class);
        declaredMethod.setAccessible(true);
        System.out.println(declaredMethod);
        Object invoke3 = declaredMethod.invoke(object, "renqi");
        System.out.println(invoke3);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值