java反射机制

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。“反”,就要先了解“正”。一般先知道类,然后通过类产生实例化对象,而反射是通过对象找类。
反射机制一般用在框架类代码编写,所以平时在框架基础上开发特性时一般用的比较少。
Class类是反射机制的基础。反射机制是跟spring 和bean的基础。

优点:

使得系统框架具有高度的灵活性和扩展性。(反射是框架设计的灵魂)

缺点:

1)可能引入性能问题
2)使得程序的逻辑不再直观
3)可移植性,因为反射依赖于java本身框架支持,如果移植到类似andriod平台可能就支持的不好。
4)多线程高并发环境下可能引入问题。
所以,任何语言特性都不能滥用,要考虑是否需要另一种更合适的语言。

很多设计模式使用java的反射机制实现非常方便,甚至连客户端的代码都不需要修改。例如下面的简单工厂的实现,不需要停运行环境,只需要改配置文件即可实现不同类的生产。

import java.io.*;
import java.lang.reflect.InvocationTargetException;

class Animal {
    void MyPrint(String str) {
        System.out.println(str);
    }

    void Show() {
        MyPrint("I'm Animal");
    }
}

class Dog extends Animal {
    @Override
    void Show() {
        MyPrint("I'm Dog");
    }
}

class Cat extends Animal {
    @Override
    void Show() {
        MyPrint("I'm Cat");
    }
}

class AnimalFactory {
    private static AnimalFactory factory = new AnimalFactory();
    private AnimalFactory() {}

    static AnimalFactory GetInst() {
        return factory;
    }

    Animal Create() {
        try {
            // 替换成你自己的文件路径
            File file = new File("C:\\Users\\Administrator\\IdeaProjects\\demo2\\src\\test.txt");
            BufferedReader reader = new BufferedReader(new FileReader(file));
            String animalName = reader.readLine();
            Class clazz = Class.forName(animalName);
            Object obj = clazz.getDeclaredConstructors()[0].newInstance();
            reader.close();
            return (Animal) obj;
            // 忽略异常处理
        } catch (IOException e) {

        } catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {

        } catch (ClassNotFoundException e) {

        }
        return null;
    }
}

你可以在执行过程中修改test.txt文件,可以看到工厂创建的类在及时地变化,而不需要重新编译代码,甚至不需要重新启动程序。

I'm Cat
I'm Cat
I'm Cat
I'm Dog

重要的是要意识到反射没有什么魔力。当你使用反射与未知类型的对象交互时,JVM 将查看该对象,并看到它属于特定的类(就像普通的 RTTI)。在对其执行任何操作之前,必须加载 Class 对象。因此,该特定类型的 .class 文件必须在本地计算机上或通过网络对 JVM 仍然可用。因此,RTTI 和反射的真正区别在于,使用 RTTI 时,编译器在编译时会打开并检查 .class 文件。换句话说,你可以用“正常”的方式调用一个对象的所有方法。通过反射,.class 文件在编译时不可用;它由运行时环境打开并检查。

反射机制的应用场景:序列化,文档提取(见类方法提取器)。

示例代码仓库:

你可能感兴趣的:(java反射机制)