反射就是程序可以访问,检测和修改它本身状态或行为的一种能力,也就是在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象,调用方法的一种机制。由于这种动态性,可以极大的增强程序的灵活性,程序不用在编译期就完成确定,在运行期仍然可以扩展。
下图是类的正常加载过程、反射原理与class对象:
Class对象的由来是将.class文件读入内存,并为之创建一个Class对象。
1.JDBC中,利用反射动态加载了数据库驱动程序。
2.Web服务器中利用反射调用了Sevlet的服务方法。
3.Eclispe等开发工具利用反射动态刨析对象的类型与结构,动态提示对象的属性和方法。
4.很多框架都用到反射机制,注入属性,调用方法,如Spring。
优点:可以动态执行,在运行期间根据业务功能动态执行方法、访问属性,最大限度发挥了java的灵活性。
缺点:对性能有影响,这类操作总是慢于直接执行java代码。
动态代理是运行时动态生成代理类。
动态代理的应用有 Spring AOP数据查询、测试框架的后端 mock、rpc,Java注解对象获取等。
JDK 原生动态代理和 cglib 动态代理。
JDK 原生动态代理是基于接口实现的,而 cglib 是基于继承当前类的子类实现的。
获取Class类对象的三种方式
public class ReflectDemo { public static void main(String[] args) throws ClassNotFoundException { //使用类的class属性来获取该类对应的Class对象 Class<Student> c1 = Student.class; System.out.println(c1); Class<Student> c2 = Student.class; System.out.println(c1 == c2); System.out.println("--------"); //调用对象的getClass()方法,返回该对象所属类对应的Class对象 Student s = new Student(); Class<? extends Student> c3 = s.getClass(); System.out.println(c1 == c3); System.out.println("--------"); //使用Class类中的静态方法forName(String className) Class<?> c4 = Class.forName("com.itheima_02.Student"); System.out.println(c1 == c4); } }
获取构造方法