简单了解什么是反射

什么是反射?

反射是一种能在运行期分析类以及操作Class对象的机制。这里有两个名词待我们了解:

一个是运行期是什么?

在Java项目启动的过程中,程序需要经历两个阶段,首先是编译期(编译器会把.java文件编译成.class文件,然后类加载器会把.class文件加载到内存中)、然后是解释运行期(JVM会把内存中的.class文件翻译成机器语言交给操作系统执行)

一个是分析类是什么?

对于一个类来说,它的元结构信息(构造器、属性、方法等)会被存储在方法区内,同时在堆内存中有一个Class对象与之对应。我们可以通过操作Class对象方式在运行期获取一个类的元结构信息,也可以通过操作Class对象方式获取或者修改类实例化对象的属性、调用其方法或者构造器,同时可以根据需要动态加载一些编译期未知的类(当程序启动,有main方法的类会被加载,同时相关的类会被递归加载,我们可以通过反射延迟加载类,加快程序的启动速度)

反射的优缺点?

优点:

可以在运行期获取类信息,无需提前知道类,有助于一些框架通用性的实现

缺点:

反射无法被JIT优化导致操作对象效率较低

破坏了封装特性,可能有安全问题

哪里用到了反射?

1.JDBC驱动就是用反射加载的

Class.forName('com.mysql.jdbc.Driver');

2.Spring框架的一些内部实现,比如实例化对象期间的默认无参构造器创建对象、初始化对象期间的属性注入等

3.动态代理反射调用代理对象的方法,并对方法增强

怎么获取Class对象?

Object obj = new Object();

// 对象.getClass
obj.getClass();

// 类.class
Object.class;

// 类.forName("全类名")
Class.forName("com.mysql.jdbc.driver");

// ClassLoader.loadClass("全类名")
ClassLoader classloader = new ClassLoader();
classloader.loadClass("xxx");

如何获取到类元结构信息?

Class clazz = Object.class;

// 获取所有访问权限的方法信息
Method[] methods = clazz.getDeclaredMethods();

// 获取所有访问权限的属性信息
Field[] field = clazz.getDeclaredFields();

// 获取所有访问权限的构造器
Constructor<?>[] Constructors = clazz.getDeclaredConstructors();

// 获取所有注解
Annotation[] annotations = clazz.getAnnotations();

如何使用Class对象获取和修改实例化对象?

// 获取属性
Field name = clazz.getField("name");

// 实例化对象
Constructor<?> constructor = clazz.getConstructor();
Object instance = constructor.newInstance();

// 调用方法
Method f1 = clazz.getMethod("f1");
Object invoke = f1.invoke(instance);

你可能感兴趣的:(java,jvm)