2.2 在运行时查找字段

序列化一个对象,需要序列化其 字段值

因此 serializeObject 方法首先要获取参数对象的 字段列表,可以通过参数对象的 class 对象实现。

class 对象提供了如下 Filed 相关方法:

方法签名 说明
Field getField(String name) 返回调用对象中名为 namepublic 字段的 Field 对象
Field getFields() 返回所有 public 字段的 Field 数组
Field getDeclaredField(String name) 返回调用对象类、接口中声明的名为 name 的字段的 Field 对象
Field getDeclaredFields() 返回调用对象类、接口声明的所有字段的 Field 数组
  • getField()
    • 本类(接口)声明 + 继承
    • public 字段。
  • getDeclaredField
    • 本类声明
    • 所有访问限定(public protected private package

可能抛出的异常:

  1. NoSuchFieldException:查询不存在的字段抛出。
  2. SecurityException:查询字段的功能可以在 Java security manager 中禁止,此时上述方法都会抛出。

需序列化对象,需要获取对象的所有字段,不管是自身声明的,还是继承自父类的,不管是 public 字段,还是 nonpublic 字段,上面四个方法无法实现该需求,需要自行实现:

Class<?> cls = obj.getClass();
List<Class> accum = new LinkedList<>();

while (cls != null) {
    // 获取该层(本类)所有字段
    Field[] fields = cls.getDeclaredFields();

    for (Field f : fields) {
        accum.add(f);
    }
    // 向上遍历
    cls = cls.getSuperclass();
}

Field[] all = (Field[]) accm.toArray(new Field[accum.size()]);

关键点

  1. 通过 getSuperclass 在继承树向上遍历。
  2. 在每一层中,通过 getDeclaredFields 获取所有字段。

这样层层遍历,就能获取对象所有字段,包含自身声明和继承而来的,也包含所有的访问权限的。

results matching ""

    No results matching ""