反射介绍及使用

梦想不抛弃苦心追求的人,只要不停止追求,你们会沐浴在梦想的光辉之中。再美好的梦想与目标,再完美的计划和方案,如果不能尽快在行动中落实,最终只能是纸上谈兵,空想一番。只要瞄准了大方向,坚持不懈地做下去,才能够扫除挡在梦想前面的障碍,实现美好的人生蓝图。反射介绍及使用,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

1、java中万物皆对象,类也是一种对象,是Class类的实例对象
2、获取类的类类型(class type)的三种方法

Class c1 = A.class;
Class c2 =a.getClass();
Class c3 =Class.forName(“类路径+类名称”);

编译时刻加载类是静态加载类、运行时刻加载类是动态加载类。Class.forName是动态加载类,跳过编译期在运行期执行

3、通过类的类类型创建对象

A a =(A) c1.newInstance();

4、通过类的类类型获取类的信息

/**
 * 获取object所属类的成员函数
 * @param object
 */
public static void printClassMethodMessage(Object object){
    //要获取类的信息,首先获取类的类类型
    Class c = object.getClass();

    //获取类的名称
    System.err.println(c.getName());

    /**
     * 获取成员函数
     * 一个成员函数就是一个Method对象
     * getMethods()获取的是所有public函数,包括父类继承来的
     * getDeclaredMethods()获取的是所有该类自己声明的方法,无关访问权限
     */
    Method[] ms = c.getMethods();
    for (int i=0;i<ms.length;i++){
        //得到方法返回值类型的类类型
        Class<?> returnType = ms[i].getReturnType();
        System.err.println(returnType.getName());
        //得到方法的名称
        System.err.println(ms[i].getName());
        //获取参数类型:得到的是参数列表的类型的类类型
        Class<?>[] parameterTypes = ms[i].getParameterTypes();
        for (Class class1:parameterTypes){
            System.err.println(class1.getName());
        }
    }

}


/**
 * 获取object所属类的成员变量
 * @param object
 */
public static void printFieldMessage(Object object){
    Class c = object.getClass();
    //获取修饰这个类的相应注解:比如TableName
    TableName annotation = (TableName) c.getAnnotation(TableName.class);


    /**
     * 获取成员变量
     * 一个成员变量就是一个Field对象
     * getFields()获取的是所有public成员变量,包括父类继承来的
     * getDeclaredFields()获取的是所有该类自己声明的成员变量,无关访问权限
     */
    Field[] fs = c.getDeclaredFields();
    for (Field field : fs){
        //获取这个成员变量的Id注解,有的成员变量id注解为null,有的不为null
        Id id = field.getAnnotation(Id.CLASS);
        //将成员变量的pvivate改成可用,这样可以操作这个成员变量
        field.setAccessible(true);
        //得到成员变量的类型的类类型
        Class<?> fieldType = field.getType();
        String typeName = fieldType.getSimpleName();
        //得到成员变量的名称
        String fieldName = field.getName();
        System.err.println(typeName+" "+fieldName);
        //得到该对象这个成员变量所对应的值
        try {
            String value = (String) field.get(object);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        field.setAccessible(false);
    }

}


/**
 * 获取object所属类的构造函数
 * @param object
 */
public static void printConMessage(Object object){
    Class c = object.getClass();

    /**
     * 获取构造函数
     * 一个构造函数就是一个Constructor对象
     * getConstructors()获取的是所有public构造函数,包括父类继承来的
     * getDeclaredConstructors()获取的是所有该类自己声明的构造函数,无关访问权限
     */
    Constructor[] cs = c.getDeclaredConstructors();
    for (Constructor constructor : cs){
        System.err.println(constructor.getName());
        //获取参数类型:得到的是参数列表的类型的类类型
        Class[] parameterTypes = constructor.getParameterTypes();
        for (Class class1 : parameterTypes){
            System.err.println(class1.getName());
        }
    }
}

5、通过method调用方法

public static void main(String[] args) {
    A a = new A();
    Class<? extends A> c = a.getClass();


    try {
        /**
         * c.getMethod("方法名","参数列表的类类型")
         * getMethod获取的是public方法
         * getDeclaredMethod获取自己声明的方法
         */
        Method m = c.getMethod("print", int.class, int.class);
//            Method m = c.getMethod("print", new Class[]{int.class, int.class});

        //m.invoke("对象","具体的参数值")
        Object o = m.invoke(a, 10, 20);
//            Object o = m.invoke(a, new Object[]{10, 20});

    } catch (Exception e) {
        e.printStackTrace();
    }


}


public class A {
    public void print(int a,int b){
        System.err.println(a+b);
    }
}

Class、Method、Field等类中的所有方法都是运行期才有效的方法,可以无视编译期

补充:泛型只在编译期有效,跳过编译期泛型就无效了,这时往容器里存任何类型都可以

public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    System.err.println(list.size());
    Class<? extends List> c = list.getClass();
    try {
        //Class、Method的方法在运行期有效,可以无视编译期,所以插入int类型的数据,依然不报错
        Method add = c.getMethod("add", Object.class);
        add.invoke(list,20);
        System.err.println(list.size());
        System.err.println(list);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/153467.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!