反射是指对于任何一个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,此时是可以为集合存入其他任意类型的元素的。
做通用框架
给你任意一个对象,在不清楚对象字段的情况可以,可以把对象的字段名称和对应值存储到文件中去。