反射是Java的高级特性之一,但是在实际的开发中,使用Java反射的案例却非常的少,但是反射确实在底层框架中被频繁的使用。
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
比如:JDBC中的加载数据库驱动程序,Spring框架中加载bean对象,动以及态代理,这些都使用到反射,因为我们要想理解一些框架的底层原理,反射是我们必须要掌握的。
理解反射我们先从他的概念入手,那么什么是反射呢?
反射就是在运行状态能够动态的获取该类的属性和方法,并且能够任意的使用该类的属性和方法,这种动态获取类信息以及动态的调用对象的方法的功能就是反射。
实现上面操作的前提是能够获取到该类的字节码对象,也就是.class文件,在反射中获取class文件的方式有三种:
类名.class 如:Person.class
对象.getClass 如:person.getClass
Class.forName(全类名)获取 如:Class.forName("com.nowjava.service")
在日常的第三方应用开发过程中,经常会遇到某个类的某个成员变量、方法或是属性是私有的或是只对系统应用开放,这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或是方法。当然,也不是所有的都适合反射,之前就遇到一个案例,通过反射得到的结果与预期不符。阅读源码发现,经过层层调用后在最终返回结果的地方对应用的权限进行了校验,对于没有权限的应用返回值是没有意义的缺省值,否则返回实际值起到保护用户的隐私目的。
反射的实际场景的应用,这里主要列举这几个方面:
动态代理
JDBC 的数据库的连接
Spring 框架的使用
对于反射的执行过程的原理,我这里画了一张图,以供大家参考理解。
我们看过JVM的相关书籍都会详细的了解到,Java文件首先要通过编译器编译,编译成Class文件,然后通过类加载器(ClassLoader)将class文件加载到JVM中。
在JVM中Class文件都与一个Class对象对应,在因为Class对象中包含着该类的类信息,只要获取到Class对象便可以操作该类对象的属性与方法。
在这里深入理解反射之前先来深入的理解Class对象,它包含了类的相关信息。
Java中我们在运行时识别对象和类的信息,也叫做RTTI,方式主要有来两种:
传统的RTTI(Run-Time Type Information)
反射机制
public class User{ private String name; private Integer age; public User() { } public User(String name, Integer age) { this.name = name; this.age = age; } private void privateMethod(){ System.err.println("privateMethod"); } public void publicMethod(String param){ System.err.println("publicMethod"+param); } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
本文系作者在时代Java发表,未经许可,不得转载。
如有侵权,请联系nowjava@qq.com删除。