private Field[] getFields(Class<?> targetClass) {
        // order: [fields of super class, ..., fields of this class]
        List<Field[]> succ = new ArrayList<Field[]>();
        int total = 0;
        for (Class<?> c = targetClass; c != Object.class; c = c.getSuperclass()) {
            Field[] fields = c.getDeclaredFields();
            total += fields.length;
            succ.add(fields);
        }
        Field[] result = new Field[total];
        int off = 0;
        for (int i = succ.size() - 1; i >= 0; i--) {
            Field[] fields = succ.get(i);
            System.arraycopy(fields, 0, result, off, fields.length);
            off += fields.length;
        }
        return result;
    }