反射是指对于任何一个Class类,在运行时动态获取类的信息以及动态调用类中成分。包括类的构造器对象、类的成员变量对象、类的成员方法对象。
获取Class类的对象
反射的第一步都是先得到编译后的Class类对象。有三种方法:1.Class类的静态方法;2.类名.class;3.对象.getclass
/** * 反射-获取class对象 */ // 1.Class类的静态方法;2.类名.class;3.对象.getclass Class c1=Class.forName("reflact_class.Student"); System.out.println(c1); Class c2=Student.class; System.out.println(c2); Class c3=new Student().getClass(); System.out.println(c3);
获取构造器对象并使用
对于构造器的不同属性和获取的特点,有四种类型的方法获取构造器:
Constructor<?>[] getConstructors() |
返回所有public构造器对象的数组 |
Constructor<?>[] getDeclaredConstructors() |
返回所有构造器对象的数组 |
Constructor<T> getConstructor(Class<?>... parameterTypes) |
返回单个public构造器对象 |
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) |
返回单个构造器对象 |
//全部的用public修饰的构造器,getConstructors Constructor[] constructors=c1.getConstructors(); for (Constructor constructor : constructors) { System.out.println(constructor.getName()+":"+constructor.getParameterCount()); } //全部的构造器,getDeclaredConstructors Constructor[] constructors2 =c1.getDeclaredConstructors(); for (Constructor constructor : constructors2) { System.out.println(constructor.getName()+"::"+constructor.getParameterCount()); } //某一个public修饰的构造器 Constructor constructor= c1.getConstructor(); System.out.println(constructor.getName()+"-"+constructor.getParameterCount()); //任意一个构造器 Constructor constructor2 = c1.getDeclaredConstructor(String.class); System.out.println(constructor2.getName()+"--"+ constructor2.getParameterCount());
获取构造器初始化一个对象返回:对于public的构造器可以直接new对象,如果不是可以用暴力反射方法:setAccessible。即 反射可以破坏封装性,私有的也可以执行。
//***public的构造器使用 Student s=(Student)constructor.newInstance(); System.out.println(s); //***非public的构造器使用---暴力反射 constructor2.setAccessible(true); Student s2=(Student)constructor2.newInstance("a"); System.out.println(s2);
获取成员变量对象并使用
使用反射技术获取成员变量对象,在某个对象中进行取值、赋值。对于是非public的成员变量,同样有暴力反射方法setAccessible,打开权限然后再取值、赋值
Field[] getFields() |
返回所有public成员变量对象的数组 |
Field[] getDeclaredFields() |
返回所有成员变量对象的数组 |
Field getField(String name) |
返回单个public成员变量对象 |
Field getDeclaredField(String name) |
返回单个成员变量对象 |
void set(Object obj, Object value): |
赋值 |
Object get(Object obj) |
取值 |
获取方法对象并使用
Method[] getMethods() |
返回所有public成员方法对象数组 |
Method[] getDeclaredMethods() |
返回所有成员方法对象的数组 |
Method getMethod(String name, Class<?>... parameterTypes) |
返回单个public成员方法对象 |
Method getDeclaredMethod(String name, Class<?>... parameterTypes) |
返回单个成员方法对象 |
Object invoke(Object obj, Object... args) |
运行方法(同样也有setAccessible) |
反射的作用
可以在运行时得到一个类的全部成分然后操作,可以破坏封装性,也可以破坏泛型的约束性。
- 绕过编译阶段为集合添加数据
反射是作用在运行时的技术,此时集合的泛型将不能产生约束了,泛型只是在编译阶段可以约束集合只能操作某种数据类型,在编译成Class文件进入运行阶段的时候,其真实类型都是ArrayList,此时是可以为集合存入其他任意类型的元素的。
- 做通用框架
给你任意一个对象,在不清楚对象字段的情况可以,可以把对象的字段名称和对应值存储到文件中去。