共计 1763 个字符,预计需要花费 5 分钟才能阅读完成。
前言
说起发射,先说正射是什么,咱们代码中通过 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);
}
}
注解获取类
正文完