java 反射

1、反射概述

Reflection(反射)是Java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的內部信息,并能直接操作任意对象的内部属性及方法。
Java反射机制主要提供了以下功能:

  • 在运行时构造任意一个类的对象
  • 在运行时获取任意一个类所具有的成员变量和方法
  • 在运行时调用任意一个对象的方法(属性)
  • 生成动态代理

2、相关API使用

Constructor:

    /**
     * 构造器
     * @param user
     */
    public static void constructor(User user) {
        Class<? extends User> aClass = user.getClass();

        Constructor[] cs = aClass.getDeclaredConstructors();
        for (Constructor constructor : cs) {
            System.out.print(constructor.getName() + "(");
            //获取构造函数的参数列表---》得到的是参数雷彪的类类型
            Class[] paramTypes = constructor.getParameterTypes();
            for (Class class1 : paramTypes) {
                System.out.print(class1.getName() + ",");
            }
            System.out.println(")");
        }
    }

Field:

    /**
     * 字段
     *
     * @param user
     * @throws Exception
     */
    public static void field(User user) throws Exception {
        Class<? extends User> aClass = user.getClass();

        System.out.println("getFields public修饰的>>>>>>>");
        Field[] fields = aClass.getFields();
        for (Field field : fields) {
            System.out.println(field.getName());
        }

        System.out.println("getDeclaredFields获取一个类的所有字段>>>>>>>");
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field : declaredFields) {
            System.out.println("field.getName()>>>" + field.getName() + "  " + field.getType().getSimpleName());
            //name属性
            if ("name".equals(field.getName())) {
                // 要设置属性可达,不然会抛出IllegalAccessException异常
                field.setAccessible(Boolean.TRUE);
                System.out.println("    1>>>" + field.get(user));
                //重新设置值
                field.set(user, "jack");
                System.out.println("    2>>>" + field.get(user));
                field.setAccessible(Boolean.FALSE);
            }
        }

        System.out.println("单个字段");
        try {
            Field name = aClass.getField("city");
            System.out.println(name.getName());
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

Method:

  /**
     * 方法
     *
     * @param user
     * @throws Exception
     */
    public static void method(User user) throws Exception {
        Class<? extends User> aClass = user.getClass();

        System.out.println("getMethods public修饰的>>>>>>>");
        Method[] methods = aClass.getMethods();
        for (Method method : methods) {
//            System.out.println(method.getName());
        }

        System.out.println("getDeclaredMethods当前类自己的所有方法>>>>>>>");
        Method[] declaredMethods = aClass.getDeclaredMethods();
        for (Method method : declaredMethods) {
            System.out.print(method.getName() + "(");

            //获取参数类型
            Class<?>[] parameterTypes = method.getParameterTypes();
            for (Class parameterType : parameterTypes) {
                System.out.print(parameterType.getName() + ",");
            }
            System.out.println(")");

            if ("print".equals(method.getName())) {
                method.invoke(user);
            }

            if ("hello".equals(method.getName())) {
                // 要设置属性可达,不然会抛出IllegalAccessException异常
                method.setAccessible(Boolean.TRUE);
                method.invoke(user);
                method.setAccessible(Boolean.FALSE);
            }

            if ("say".equals(method.getName())) {
                // 要设置属性可达,不然会抛出IllegalAccessException异常
                method.setAccessible(Boolean.TRUE);
                //参数对上
                method.invoke(user, "yyy");
                method.setAccessible(Boolean.FALSE);
            }
        }

        Method method = aClass.getMethod("print");
        System.out.println("method.getName()=====" + method.getName());
    }

 3、Class获取方式

//实际告诉我们任何一个类都有一个隐含的静态成员变量class(知道类名时用),不会触发初始化
Class c1 = User.class;

//已知该类的对象通过getClass方法(知道对象时用)
Class c2 = user.getClass();  

//会有一个ClassNotFoundException异常,会触发初始化
Class c3 = Class.forName("类的路径全名");

可用Class进行对象实例创建:

//前提是必须要有无参的构造方法,因为该语句会去调用其无参构造方法。该语句会抛出异常。
User user = (User)c1.newInstance();

 

源码参照:Github

  

posted @ 2019-03-06 22:52  花拾夕  阅读(336)  评论(0编辑  收藏  举报