JAVA反射入门

来源:互联网 发布:qq空间皮肤psd源码 编辑:程序博客网 时间:2024/06/06 09:44

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

一、关于Class

    1、Class是一个类,一个描述类的类(也就是描述类本身),封装了描述方法的Method,描述字段的Filed,描述构造器的Constructor等属性
    2、对象照镜子后(反射)可以得到的信息:某个类的数据成员名、方法和构造器、某个类到底实现了哪些接口。
    3、对于每个类而言,JRE 都为其保留一个不变的 Class 类型的对象。
    4、Class 对象只能由系统建立对象
    5、一个类在 JVM 中只会有一个Class实例

二、反射的基本知识

String s = new String("AAA");        //通过类名.class方法获得        System.out.println(String.class.getName());        // 通过全类名获取        System.out.println(Class.forName("java.lang.String").getName());        //通过对象的getClass()方法获取        Class c = s.getClass();        System.out.println(s.getClass().getName());

我们还可以获得父类的class信息

        System.out.println(c.getSuperclass().getName());

Constructor[] con = c.getConstructors();//获得构造器        Field[] fieldArray = c.getDeclaredFields();//获得属性        Method[] methods = c.getMethods();//获得方法        Class[] InterArray = c.getInterfaces();//获得接口信息

在这个过程中,我们可以得到他们的修饰符、返回值信息等

除此之外还包括注解等信息

可以得出结论,利用反射,我们可以重现原来的JAVA文件,这一点在动态代理中特别重要

三、通过反射机制为集合添加元素

public static void TestGeneric(){        List list1 = new ArrayList(); // 没有泛型        List<String> list2 = new ArrayList<String>(); // 有泛型        /*         * 1.首先观察正常添加元素方式,在编译器检查泛型,         * 这个时候如果list2添加int类型会报错         */        list2.add("Hello Java");        //list2.add(1); // 报错!list2有泛型限制,只能添加String,添加int报错        /*         * 2.然后通过反射添加元素方式,在运行期动态加载类,首先得到list1和list2         * 的类类型相同,然后再通过方法反射绕过编译器来调用add方法,看能否插入int         * 型的元素         */        Class c1 = list1.getClass();        Class c2 = list2.getClass();        System.out.println(c1 == c2); // 结果:true,说明类类型完全相同        // 验证:我们可以通过方法的反射来给list2添加元素,这样可以绕过编译检查        System.out.println("list2的长度是:"+list2.size());        try {            Method m = c2.getMethod("add",Object.class); // 通过方法反射得到add方法            m.invoke(list2, 1); // 给list2添加一个int型的,上面显示在编译器是会报错的            m.invoke(list2,false);            System.out.println("list2的长度是:" + list2.size());            // 结果:2,说明list2长度增加了,并没有泛型检查        } catch (Exception e) {            e.printStackTrace();        }        /*现在list2的产生是3,说明运行期间,泛型就不起作用了*/    }