java反射

简介

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

原理

《深入理解Java虚拟机》一文中介绍,类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载、连接、初始化、使用、卸载。而JVM在加载阶段要完成的3件事情中正好有Class对象的生成:

  1. 通过一个类的全限定名来获取定义此类的二进制字节流。
  2. 将这个字节流所代表的的静态存储结构转化为方法区的运行时数据结构。
  3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

获取一个类的Class对象的三种方法,对应的通过Class对象创建类实例也有三种方法:

// 通过包名+类名
Class<TestClass> class = Class.forName("com.zkw.TestClass");

// 通过类名
Clas<TestClass> class = TestClass.class;

// 通过对象
TestClass tc = new TestClass();
Class<TestClass> class = tc.getClass();
 
// 通过Class对象创建类实例
TestClass testClass = class.newInstance();

使用

在正式开始前,先介绍一个最重要的方法setAccessible(),使用反射可以获取一个类的所有方法及属性,但是某些方法和属性是私有的,这时候就需要通过该方法将方法和类设置为public;

注: setAccessible()方法并不是修改类的访问权限,而是是否禁止Java 语言访问检查(值为true则禁止)
在这里插入图片描述

相关类

类名用途
Class类代表类的实体,在运行的Java应用程序中表示类和接口
Field类代表类的成员变量(成员变量也称为类的属性)
Method类代表类的方法
Constructor类代表类的构造方法

class类

● 获得类相关的方法
方法用途
Cast把对象转换成代表类或是接口的对象
getClassLoader()获得类的加载器
getClasses()返回一个数组,数组中包含该类中所有公共类和接口类的对象
getDeclaredClasses()返回一个数组,数组中包含该类中所有类和接口类的对象
forName(String className)根据类名返回类的对象
getName()获得类的完整路径名字
newInstance()创建类的实例(不推荐使用,而是使用Constructor的newInstance()方法)
getPackage()获得类的包
getSimpleName()获得类的名字
getSuperclass()获得当前类继承的父类的名字
getInterfaces()获得当前类实现的类或是接口
● 获得类中属性相关的方法
方法用途
getField(String name)获得某个公有的属性对象
getFields()获得所有公有的属性对象
getDeclaredField(String name)获得某个属性对象
getDeclaredFields()获得所有属性对象
● 获得类中注解相关的方法
方法用途
getAnnotation(Class annotationClass)返回该类中与参数类型匹配的公有注解对象
getAnnotations()返回该类所有的公有注解对象
getDeclaredAnnotation(Class annotationClass)返回该类中与参数类型匹配的所有注解对象
getDeclaredAnnotations()返回该类所有的注解对象
● 获得类中构造器相关的方法
方法用途
getConstructor(Class…<?> parameterTypes )获得该类中与参数类型匹配的公有构造方法
getConstructors()获得该类的所有公有构造方法
getDeclaredConstructor(Class…<?> parameterTypes)获得该类中与参数类型匹配的构造方法
getDeclaredConstructors()获得该类所有构造方法
● 获得类中方法相关的方法
方法用途
getMethod(String name, Class…<?> parameterTypes)获得该类某个公有的方法
getMethods()获得该类所有公有的方法
getDeclaredMethod(String name, Class…<?> parameterTypes)获得该类某个方法
getDeclaredMethods()获得该类所有方法

Field类

方法用途
equals(Object obj)属性与obj相等则返回true
get(Object obj)获得obj中对应的属性值
set(Object obj, Object value)设置obj中对应属性值
getModifiers()获取该属性的修饰符(static、final等)

Method类

方法用途
invoke(Object obj, Object… args)传递object对象及参数调用该对象对应的方法

Constructor类

方法用途
newInstance(Object… initargs)根据传递的参数创建类的对象

实战

在日常开发中反射用的最多的地方可能是将map转换为实体bean:

publicclass MapUtilByReflect {

    /**
     * 对象转Map
     * @param object
     * @return
     * @throws IllegalAccessException
     */
    public static Map beanToMap(Object object) throws IllegalAccessException {
        Map<String, Object> map = new HashMap<String, Object>();
        // 获取所有属性
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            // 禁止Java 语言访问检查
            field.setAccessible(true);
            map.put(field.getName(), field.get(object));
        }
        return map;
    }

    /**
     * map转对象
     * @param map
     * @param beanClass
     * @param <T>
     * @return
     * @throws Exception
     */
    publicstatic <T> T mapToBean(Map map, Class<T> beanClass) throws Exception {
        T object = beanClass.newInstance();
        Field[] fields = object.getClass().getDeclaredFields();
        for (Field field : fields) {
            int mod = field.getModifiers();

            // 一定不要忘记加上该判断
            if (Modifier.isStatic(mod) || Modifier.isFinal(mod)) {
                continue;
            }
            
            field.setAccessible(true);
            if (map.containsKey(field.getName())) {
            	 // 赋值
                field.set(object, map.get(field.getName()));
            }
        }
        return object;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值