反射在java中占据很重要的地位,spring的IOC/DI背后依靠的就是java的反射机制。不仅spring使用反射机制,Hibernate的ORM框架也是反射机制实现的,AOP动态代理也大量使用了反射技术,在不知不觉中,java的反射机制其实已经被大量应用在我们的程序中。
java反射机制是在运行状态中,对于任意一个类,都能知道这个类的所有属性方法;对于任意一个对象都能调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能成为java的反射机制。
反射的优点就是动态灵活,一切都是在运行时期根据具体情况(配置)决定创建哪种对象、调用哪个方法等。这种灵活性可以方便我们设计解耦,这也是Spring做得最好的事情之一,所以我们可以很方便的替换某些class文件而不需要重新编译相关类。事物都是两面的,反射当然也有缺点,对于编译期能确定的事情,编译器可以或多或少做些优化,而运行期就像解释执行一样,编译器一般没法进行优化,所以使用反射性能要打点折扣;另外反射破坏类的封装性,通过反射我们可以访问类的任何成员,包括private成员,这违反了面向对象设计原则。
java.lang.Class类:反射中最常出现的类,它跟其它JAVA类没什么两样只是名字恰巧叫Class,都是继承于Object类,其实它就是JAVA类的抽象,用来描述类的元数据,比如每个类都有类名、装载器、哈希等,这些都是Class类的属性。Class没有public的构造函数,当Java虚拟机载入一个类的时候,它就会自动创建一个Class类的实例来表示这个类,比如java.lang.String,我们可以通过String.class来获取对应的Class类实例;或者我们也可以通过Class.forName("类全名")来获取一个Class对象。
类加载:
当JVM第一次使用一个类时,需要通过ClassPath找到这个类对应的.class文件,把这个文件中包含的类的信息读入JV并保存起来一般的说,一个类只会加载一次。
反射常用方法介绍:
1. Class: 是一个类; 一个描述类的类.
封装了描述方法的 Method,
描述字段的 Filed,
描述构造器的 Constructor 等属性.
2. 获取Class对象的三种方式.
2.1>Class.forName("完整的类名字符串");
2.2>类名.class
2.3>指定类对象.getClass();
最常用的是Class.forName("完整的类名字符串");
3. 关于 Method:
3.1 如何获取 Method:
Method[] getMethods[];获取当前类所有的public修饰的成员方法;这里会显示父类继承而来的方法
Method[] getDeclaredMethods(); 获取当前类里面的所有方法,包括private修饰的方法,但是会guolv父类继承而来的方法
Method getMethod(String methodName,Object... args); 根据方法的名字和对应的参数列表,获取指定方法
Method getDeclaredMethod(String methodName,Object... args); 根据方法的名字和对应的参数列表,获取指定方法;可以获取private修饰的方法
3.2 如何调用 Method
1). 如果方法时 private 修饰的, 需要先调用 Method 的 setAccessible(true), 使其变为可访问
2). method.invoke(obj, Object ... args);第一个参数是执行该方法的类对象,第二个是执行该方法需要的参数列表
4. 关于 Field:
4.1 如何获取
Field[] getFields(); 获取所有的用public修饰的成员变量
Field[] getDeclaredFields(); 获取所有的成员变量,包括private修饰在类的成员变量
Field getField(String fieldName); 根据成员变量的名字获取成员变量
Field getDeclaredField(String fieldName); 根据成员变量的名字获取包括private修饰在内的成员变量
4.2 如何获取 Field 的值:
1). setAccessible(true)
2). field.get(Object obj)
4.3 如何设置 Field 的值:
field.set(Obejct obj, Object val)) 设置成员变量的数值,第一个参数是调用该成员变量的对象,第二个参数是赋予数值
5.Constructor常用方法
Constructor[] getConstructor();获取所有的public修饰的构造方法
Cosntructor getDeclaredConstructor();获取当前类里面所有的构方法,包含私有化的构造方法
Constructor getConstructor(Object... paramterTyeps); 根据所需参数不同,获取指定的构造方法对象
Constructor getDeclaredConstructor(Object... paramterTyeps); 根据所需参数不同,获取指定的构造方法对象包含私有化的构造方法
Object newInstance(Object... initargs); 给予确定的参数,通过反射嗲用构造方法,这里的参数列表是一个不定参数列表
6.暴力反射赋予权限的函数是 setAccessible(boolean boolea)
如有不足,欢迎留言指正。望不吝赐教。。。