【JAVA基础】 反射相关知识

这段时间在重温反射的知识,得到一些新的体会,对这方面知识也得到了进一步巩固,做个笔记下次方便找

一、反射的概念

  • 在java中秉承着一切皆对象的原则,管理类的对象叫做Class,管理构造方法的类叫做Constructor,管理成员方法的类叫做Method,管理成员变量的类叫做Field,我们反射第一步就是拿到Class,再对其进行操作。
  • 利用反射创建的对象可以不受访问修饰符的限制,调用使用类里面所有的内容
  • 反射到底学些什么知识
    • 如何获取class字节码文件的对象
    • 利用反射获取构造方法并且创建对象
    • 利用反射获取成员变量并且赋值获取值
    • 利用反射获取成员方法并且调用方法

二、获取class对象的方法

  • Class.forName("全类名");
  • 类.class;
  • 对象.getClass();
 //1.Class.forName("全限类名")
        Class<?> aClass = Class.forName("com.eva.entity.UserEntity");
        log.debug("{}",aClass);
        //2.类名.class
        Class<UserEntity> userEntityClass = UserEntity.class;
        log.debug("{}",userEntityClass);
        //3.对象.getClass()
        UserEntity userEntity = new UserEntity();
        Class<? extends UserEntity> aClass1 = userEntity.getClass();
        log.debug("{}",aClass1);

三、java源码和字节码文件区别

  • java源码文件:我们自己写的代码
  • 字节码文件:java源码编译后的class文件,存在于硬盘中,这个操作不需要我们自己操作,jdk有方法将java文件编译成class字节码文件
  • 字节码文件对象:在内存当中运行的是class字节码文件,当class字节码文件加载到内存中的时候,jvm会自动创建出一个Class对象,用来管理class字节码文件,这个Class对象中包括了class字节码中的全部内容.我们反射得到的就是Class对象,因为jvm进行类加载只执行一次,所以这个Class对象在内存中是唯一的.

四、获取构造方法 

方法作用

返回类型

方法名

得到所有公共构造方法

Constructor<?>[]

getConstructors()

得到所有构造方法

Constructor<?>[]

getConstructors()

得到单个公开构造方法

Constructor<?>[]

getConstructors()

得到单个非公开构造方法

Constructor<T>

getDeclaredConstructor(Class<?>... parameterTypes)

/**
         * 反射得到类中的构造方法并且通过构造方法创建对象
         */
        Class<UserEntity> userEntityClass = UserEntity.class;
        //1.得到所有公共构造方法-->getConstructors()
        Constructor<?>[] constructors = userEntityClass.getConstructors();
        for (Constructor<?> constructor : constructors) {
            log.debug("{}",constructor);
        }
        //2.得到所有的构造方法-->getDeclaredConstructors()
        Constructor<?>[] declaredConstructors = userEntityClass.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            log.debug("{}",declaredConstructor);
        }
        //3.得到单个公开构造方法-->getConstructor(CLass<?>... parameterTypes)
        try {
            Constructor<UserEntity> constructor = userEntityClass.getConstructor(null);
            log.debug("{}",constructor);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
        //4.得到单个私有的构造方法-->getDeclaredConstructor(CLass<?>... parameterTypes)
        try {
            Constructor<UserEntity> declaredConstructor = userEntityClass.getDeclaredConstructor(String.class, String.class);
            log.debug("{}",declaredConstructor);
            declaredConstructor.setAccessible(true);
            UserEntity userEntity = declaredConstructor.newInstance("张三", "男");
            log.debug("{}",userEntity.song());
        } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
        //5.得到单个受保护的构造方法-->getDeclaredConstructor(CLass<?>... parameterTypes)
        try {
            Constructor<UserEntity> declaredConstructor = userEntityClass.getDeclaredConstructor(String.class, String.class, int.class);
            declaredConstructor.setAccessible(true);
            UserEntity userEntity = declaredConstructor.newInstance("小红", "女", 18);
            log.debug("{}",userEntity.getName());
        } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }

五、获取成员方法

获取所有的公共方法

Method[]

getMethods()

获取所有的方法

Method[]

getDeclaredMethods()

获取单个的公共方法

Method

getMethod(String name, Class<?>... parameterTypes)

获取单个私有方法

Method

getDeclaredMethod(String name, Class<?>... parameterTypes)

 /**
         * 反射获取成员方法
         */
        /*第一步:获取该类的Class对象*/
        Class<UserEntity> userEntityClass = UserEntity.class;
        /*1.获取所有的公共方法(包括父类所有的公共方法)*/
        Method[] methods = userEntityClass.getMethods();
        for (Method method : methods) {
            log.debug("{}", method);
        }
        /*2.获取所有的方法(包括自身private修饰的方法,但是不包括父类的方法)*/
        Method[] declaredMethods = userEntityClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            log.debug("{}", declaredMethod);
        }
        /*3.获取单个的公共方法-->getMethod(String name, Class<?>... parameterTypes)
        参数一:方法名
        参数二:形参类型
        原因:为了区分重载方法,方法唯一性:方法名+形参类型和个数*/
        Method song = userEntityClass.getMethod("song");
        log.debug("{}", song);
        /*4.获取单个私有方法*/
        Method dance = userEntityClass.getDeclaredMethod("dance", String.class);
        /*4.1 获取修饰符 public: 1  private: 2  protected: 4 */
        int modifiers = dance.getModifiers();
        log.debug("{}", modifiers);

        /*4.2 获取方法名*/
        String name = dance.getName();
        log.debug("{}", name);

        /*4.3 获取形参*/
        Parameter[] parameters = dance.getParameters();
        for (Parameter parameter : parameters) {
            log.debug("{}", parameter);
        }

        /*4.4 获取抛出的异常*/
        Class<?>[] exceptionTypes = dance.getExceptionTypes();
        for (Class<?> exceptionType : exceptionTypes) {
            log.debug("{}", exceptionType);
        }

        /*4.5 使用方法
         * Method类中用于创建对象的方法
         *     Object invoke(Object obj, Object... args):运行方法
         *     参数一:表示方法的调用对象
         *     参数二:调用方法的传递的参数(如果没有就不写)
         *     返回值:方法的返回值(如果没有就不写)
         */
        /*使用Class创建一个对象*/
        UserEntity userEntity = userEntityClass.newInstance();
        userEntity.setName("甄嬛");
        //dance方法是私有的,用setAccessible(true)临时取消权限校验
        dance.setAccessible(true);
        //参数一 userEntity:表示方法的调用对象
        //参数二 惊鸿舞:调用方法的传递的参数
        String r = (String) dance.invoke(userEntity, "惊鸿舞");
        log.debug("{}", r);

六、获取成员变量

   /*第一步:获取Class对象*/
        Class<UserEntity> userEntityClass = UserEntity.class;
        /*1.获取所有公共属性*/
        Field[] fields = userEntityClass.getFields();
        for (Field field : fields) {
            log.debug("{}", field);
        }
        /*2.获取所有属性*/
        Field[] declaredFields = userEntityClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            log.debug("{}", declaredField);
        }
        /*3.获取单个私有属性*/
        Field declaredField = userEntityClass.getDeclaredField("name");
        /*3.1 获取属性值*/
        UserEntity userEntity = userEntityClass.newInstance();
        userEntity.setName("爱坤");
        declaredField.setAccessible(true);
        String value = (String) declaredField.get(userEntity);
        log.debug("{}", value);
        /*3.2 给属性赋值*/
        declaredField.set(userEntity, "闲来");
        value = (String) declaredField.get(userEntity);
        log.debug("{}", value);

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值