Java反射机制

作者: StrongZhao | 来源:发表于2019-04-07 12:47 被阅读4次

    一、什么是反射?

    反射是指计算机程序在运行时访问、检测和修改它本身状态或行为的一种能力,是一种元编程语言的特性,有许多语言都提供了对反射机制的支持,她使程序能够编写程序,Java的反射机制使得Java能够动态的获取类的信息和调用对象的方法。

    二、反射机制的功能

    • 在运行时可以知道任意一个对象所属的类
    • 在运行时构造任意一个类的对象
    • 在运行时获取任意一个类所具有的成员变量和方法信息
    • 在运行时可以调用任意一个对象的方法
    • 生成动态代理

    三、Java反射机制及基本用法

    在Java中,Class是反射编程的起点,代表运行时类型信息(Run-Time Type Identification)。java.lang.reflect包中包含了Java支持反射的主要组件,如Constructor、Field、Method等,分别表示类的构造器、属性、方法,关系如下图:


    image.png

    Constructor和Method与Field的区别在于前者继承自抽象类Executable,是可以在运行时动态调用的,而Field仅仅具备可访问的特性,且默认为不可访问。下面了解下它们的基本用法:


    image.png

    四、Java反射API用法

    • 获取Class三种方式
    // 1. 采用Class.forName获取类的Class对象
    Class clazz = Class.forName("com.zhq.test.ReflectTest");
    System.out.println("clazz:" + clazz);
    // 2. 采用.class方法获取类的Class对象
    Class clazz1 = ReflectTest.class;
    System.out.println("clazz1:" + clazz1);
    // 3. 采用getClass方法获取类的Class对象
    ReflectTest reflectTest = new ReflectTest();
    Class clazz2 = reflectTest.getClass();
    System.out.println("clazz2:" + clazz2);
    // 4. 判断Class对象是否相同
    System.out.println("Class对象是否相同:" + ((clazz.equals(clazz1)) && (clazz1.equals(clazz2))));
    //不同类加载器加载的同一个类,也会获取不同的Class对象
    // 自定义类加载器
    ClassLoader myLoader = new ClassLoader() {
        @Override
        public Class<?> loadClass(String name) throws ClassNotFoundException {
            try {
                String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";
                InputStream is = getClass().getResourceAsStream(fileName);
                if (is == null) {
                    return super.loadClass(name);
                }
                byte[] byteArray = new byte[is.available()];
                is.read(byteArray);
                return defineClass(name, byteArray, 0, byteArray.length);
            } catch (IOException e) {
                throw new ClassNotFoundException(name);
            }
        }
    };
    // 采用自定义类加载器加载
    Class clazz3 = Class.forName("com.zhq.test.ReflectTest", true, myLoader);
    // clazz与clazz3并不相同
    System.out.println("Class对象是否相同:" + clazz.equals(clazz3));
    

    ps:三种方式获取的Class对象相同的前提是使用了相同的类加载器,Java默认采用应用程序类加载器(sun.misc.Launcher$AppClassLoader)。不同类加载器加载的同一个类,也会获取不同的Class对象

    相关文章

      网友评论

        本文标题:Java反射机制

        本文链接:https://www.haomeiwen.com/subject/hgtsiqtx.html