反射机制指的是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有属性和方法。
Java的反射可以:
Object obj = // ... 任意对象;
Class<?> clazz = obj.getClass();
// 获取成员变量
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
System.out.println("成员变量: " + field.getName());
}
// 获取方法
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
System.out.println("方法: " + method.getName());
}
Method method = clazz.getDeclaredMethod("methodName", // 方法参数类型...);
method.setAccessible(true); // 如果方法是私有的
method.invoke(obj, // 方法参数...);
// 默认构造函数
Object obj = clazz.newInstance();
// 或者使用特定的构造函数
Constructor<?> constructor = clazz.getConstructor(// 参数类型...);
Object obj = constructor.newInstance(// 构造函数参数...);
反射的好处就是可以提升程序的灵活性和扩展性,比较容易在运行期干很多事情。但是他带来的问题更多,主要由以下几个:
1、代码可读性低及可维护性
2、反射代码执行的性能低
3、反射破坏了封装性
所以,我们应该在业务代码中应该尽量避免使用反射。但是,作为一个合格的Java开发,也要能读懂中间件、框架中的反射代码。在有些场景下,要知道可以使用反射解决部分问题。
那么,反射为什么慢呢?主要由以下几个原因:
1、由于反射涉及动态解析的类型,因此不能执行某些Java虚拟机优化,如JIT优化。
2、在使用反射时,参数需要包装(boxing)成Object[] 类型,但是真正方法执行的时候,又需要再拆包(unboxing)成真正的类型,这些动作不仅消耗时间,而且过程中也会产生很多对象,对象一多就容易导致GC,GC也会导致应用变慢。
3、反射调用方法时会从方法数组中遍历查找,并且会检查可见性。这些动作都是耗时的。
4、不仅方法的可见性要做检查,参数也需要做很多额外的检查。
Java的Class类是java反射机制的基础,通过Class类我们可以获得关于一个类的相关信息
Java.lang.Class是一个比较特殊的类,它用于封装被装入到JVM中的类(包括类和接口)的信息。当一个类或接口被装入到JVM时便会产生一个与之关联的java.lang.Class对象,可以通过这个Class对象对被装入类的详细信息进行访问。
虚拟机为每种类型管理一个独一无二的Class对象。也就是说,每个类(型)都有一个Class对象。运行程序时,Java虚拟机(JVM)首先检查是否所要加载的类对应的Class对象是否已经加载。如果没有加载,JVM就会根据类名查找.class文件,并将其Class对象载入。