前言
说起发射,先说正射是什么,咱们代码中通过User user = new User();
代码创立一个对象,并调用User类的成员变量或办法,这种咱们通过Class信息获取class实例,称之为正射,这种代码编译器编译时便晓得他会生成一个user对象。
如果咱们在写代码时不晓得咱们要操作的对象类型,他可能是User类型,也可能是House类型,而User类型和Clazz类型有没有继承关系,只晓得要调用他的getId()办法,那又该怎么调用对象的办法呢?
反射
对于反射而言,咱们取得了一个对象的实例,并且晓得了这个对象的类型,那么咱们便能够对他进行所有操作。
这是因为JVM为每一个加载的class都创立了一个class实例,并保留了实例的所有信息,包含类型,父类,办法,属性等等,这使得咱们能够获取class实例的所有信息。
这种通过class实例获取class信息的办法称为反射
获取class又3种办法
通过一个class的动态变量class获取
Class clazz = User.class;
通过完整包门路获取
Class clazz = Class.forName("xiaoqiangZzz.busticket;");
通过实例获取
Object object = getObject();Class clazz = object.getClass();
获取到class后,咱们也能够通过class创立实例对象
Object object = clazz.newInstance();
获取属性
Field getField(name):
依据字段名获取某个public的field(包含父类)Field getDeclaredField(name):
依据字段名获取以后类的某个field(不包含父类)Field[] getFields():
获取所有public的field(包含父类)Field[] getDeclaredFields():
获取以后类的所有field(不包含父类)
public void getId(Object object) throws IllegalAccessException { Class clazz = object.getClass(); Field field = clazz.getField("age"); field.setAccessible(true); System.out.println(field.get(object)); field.setAccessible(false); }
相似的,咱们能够获取办法并调用
Method getMethod(name, Class...):
获取某个public的Method(包含父类)Method getDeclaredMethod(name, Class...):
获取以后类的某个Method(不包含父类)Method[] getMethods():
获取所有public的Method(包含父类)Method[] getDeclaredMethods():
获取以后类的所有Method(不包含父类)
public void getMethod(Object object) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class clazz = object.getClass(); Method method = clazz.getMethod("getId"); method.invoke(object);}
反射利用
制作一个通用的数据库表导出办法
public void wirte(Object[] objects, Class classN) throws IllegalAccessException { Sheet sheet = new Sheet(); Field[] fields = classN.getDeclaredFields(); for (int i = 1; i < objects.length; i++) { Row row = sheet.createRow(i); for (Field field : fields) { field.setAccessible(true); // 写入单元格 ........... field.setAccessible(false); } }
注解获取类