前言

说起发射,先说正射是什么,咱们代码中通过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);        }    }

注解获取类