Github user aljoscha commented on a diff in the pull request: https://github.com/apache/flink/pull/5097#discussion_r156088318 --- Diff: flink-core/src/main/java/org/apache/flink/api/java/typeutils/TypeExtractionUtils.java --- @@ -338,4 +340,78 @@ public static boolean hasSuperclass(Class<?> clazz, String superClassName) { } return Object.class; } + + /** + * Count the number of all accessible fields in the current class that are not + * declared static, transient, or final. + */ + public static int countFieldsInClass(Class<?> clazz) { + int fieldCount = 0; + for (Field field : getAllDeclaredFields(clazz, true)) { + if (!Modifier.isStatic(field.getModifiers()) && !Modifier.isTransient(field.getModifiers()) && + !Modifier.isFinal(field.getModifiers())) { + fieldCount++; + } + } + return fieldCount; + } + + /** + * Returns the declared field with the given name in a class hierarchy. The field might be private. Returns + * null if such a field does not exist. + */ + public static Field getDeclaredField(Class<?> clazz, String name) { + for (Field field : getAllDeclaredFields(clazz, true)) { + if (field.getName().equals(name)) { + return field; + } + } + return null; + } + + /** + * Recursively determine all declared fields that are not static, transient, or final. + * This is required because class.getFields() is not returning fields defined + * in parent classes. + * + * @param clazz class to be analyzed + * @param ignoreDuplicates if true, in case of duplicate field names only the lowest one + * in a hierarchy will be returned; throws an exception otherwise + * @return list of fields + */ + public static List<Field> getAllDeclaredFields(Class<?> clazz, boolean ignoreDuplicates) { + List<Field> result = new ArrayList<>(); + while (clazz != null) { + Field[] fields = clazz.getDeclaredFields(); + for (Field field : fields) { + if (Modifier.isStatic(field.getModifiers()) || Modifier.isTransient(field.getModifiers()) || + Modifier.isFinal(field.getModifiers())) { + continue; // we have no use for transient, static, or final fields + } + if (hasFieldWithSameName(field.getName(), result)) { --- End diff -- Isn't this simply `result.stream().anyMatch(f -> f.getName().equals(field.getName()))`?
---