JAVA重要知识点
反射
定义
反射是框架的灵魂,赋予了在运行时分析类和执行类中的方法的能力。
通过反射可以获取任意一个类的所有属性和方法,还可以调用这些方法和属性
应用场景
Spring/Spring Boot,MyBatis等框架。以及框架中的动态代理,动态代理的实现也依赖反射。
注解的实现也用到了反射。
优缺点
优点:令代码更加灵活,为各种框架提供开箱即用的功能提供了便利
缺点:让代码在运行时就有了分析操作类的能力,增加了安全问题。例如:无视泛型参数的安全检查,反射的性能稍差
反射获取类对象的四种方式
类对象将一个类的方法,变量等信息告诉运行的程序。
知道具体类的情况
一般是不知道具体类的,基本都是通过遍历包下面的类来获取 Class 对象,通过此方式获取 Class 对象不会进行初始化
Class alunbarClass = TargetObject.class;
通过Class.forName()传入类的全路径进行获取类对象
Class alunbarClass1 = Class.forName(
"cn.javaguide.TargetObject");
通过对象实例获取instance.getClass()
TargetObject o = new TargetObject();
Class alunbarClass2 = o.getClass();
通过类加载器传入类路径获取xxxClassLoader.loadClass()
ClassLoader.getSystemClassLoader().loadClass(
"cn.javaguide.TargetObject");
通过类加载器获取 Class 对象不会进行初始化,意味着不进行包括初始化等一系列步骤,静态代码块和静态对象不会得到执行
反射的使用
创建一个反射操作的类
package cn.javaguide;
public class TargetObject {
private String value;
public TargetObject() {
value = "JavaGuide";
}
public void publicMethod(String s) {
System.out.println("I love " + s);
}
private void privateMethod() {
System.out.println("value is " + value);
}
}
使用反射来操作这个类
package cn.javaguide;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Main {
public static void main(String[] args) throws
ClassNotFoundException, NoSuchMethodException,
IllegalAccessException, InstantiationException,
InvocationTargetException, NoSuchFieldException {
/**
* 获取 TargetObject 类的 Class 对象并且创建
* TargetObject 类实例
*/
Class<?> targetClass =
Class.forName("cn.javaguide.TargetObject");
TargetObject targetObject = (TargetObject)
targetClass.newInstance();
/**
* 获取 TargetObject 类中定义的所有方法
*/
Method[] methods = targetClass.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method.getName());
}
/**
* 获取指定方法并调用
*/
Method publicMethod = targetClass.getDeclaredMethod(
"publicMethod",
String.class);
publicMethod.invoke(targetObject, "JavaGuide");
/**
* 获取指定参数并对参数进行修改
*/
Field field = targetClass.getDeclaredField("value");
//为了对类中的参数进行修改我们取消安全检查
field.setAccessible(true);
field.set(targetObject, "JavaGuide");
/**
* 调用 private 方法
*/
Method privateMethod = targetClass.getDeclaredMethod(
"privateMethod");
//为了调用private方法我们取消安全检查
privateMethod.setAccessible(true);
privateMethod.invoke(targetObject);
}
}
输出:
publicMethod
privateMethod
I love JavaGuide
value is JavaGuide