我有一个实体分为几个类
public abstract class OneBaseAbstract {
private Long id;
private String name;
public OneBaseAbstract() {
}
...
}
第二
public abstract class TwoBaseAbstract extends OneBaseAbstract{
private Integer num;
private String mark;
public TwoBaseAbstract() {
super();
}
...
}
第三
public class Produce extends TwoBaseAbstract {
private String name2;
private String product;
public Produce() {
super();
}
...
}
实体中有几十个字段,很多表,为了测试手动填写,可能会耗费大量时间和大量错误。我有自动对象创建,但这仅适用于没有祖先的类。
这是一个解析对象的类,用任意数据填充它。
/**класс утилит для заполнения значений поля объекта*/
public final class FieldProcessForFillUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(FieldProcessForFillUtils.class);
private static final String LOGGER_MESSAGE_DATA_TYPE = "The data type is not defined here.";
/**
* Заполнение полей объекта.
* @param object - обрабатываемый объект, любого типа данных
* @param values - коллекция значений, которые будут сгенерированы для полей обрабатываемого объекта
* @param <S> - универсальный параметр, указывает на тип данных передаваемого объекта
* @return - возвращает обработанный объект. S - универсальный параметр, хранит информацию об текущем
* обрабатываемом объекте
*/
public static <S> S fillData (S object, List<Object> values){
return obtainMetadataOfObject(object, values);
}
/**
* Извлечение метаданных из полученного объекта, для дальнейшей обработки
* @param object - обрабатываемый объект
* @param values - коллекция значений, которые будут сгенерированы для полей обрабатываемого объекта
* @param <S> - универсальный параметр, указывает на тип данных передаваемого объекта
* @return - возвращает обработанный объект. S - универсальный параметр, хранит информацию об текущем
* обрабатываемом объекте
*/
private static <S> S obtainMetadataOfObject(S object, List<Object> values){
Class<?> objectClass = object.getClass();
Field[] fields = objectClass.getDeclaredFields();
parseArrFields(fields, object, values);
return object;
}
/**парсинг массива полей*/
private static void parseArrFields(Field [] fields, Object object, List<Object> values){
for(Field field : fields){
Class<?> type = field.getType();
String typeName = type.getSimpleName();
setValue(field, typeName, object, values);
}
}
/**
*
* @param field - поле для изменения
* @param typeName - имя типа данных текущего поля
* @param object - объект, поле которого обрабатываются на текущий момент
* @param values - коллекция , куда будут заносится сгенерированные значения,
* которые будут установлены в обрабатываемые поля текущего объекта
*/
private static void setValue(Field field, String typeName, Object object, List<Object> values){
Integer yearMin = 2017;
Integer yearMax = 2019;
Long minLimitForRandom = 1L;
Long maxLimitForRandom = 200000L;
switch (typeName){
case "Long" : /* тип данных*/
field.setAccessible(true);
try {
Double aDouble = randomNumberGenerator(maxLimitForRandom , minLimitForRandom);
Long id = aDouble.longValue();
field.set(object, id);
values.add(id);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
break;
case "Integer":
field.setAccessible(true);
try {
Integer number = randomNumberGenerator(maxLimitForRandom, minLimitForRandom).intValue();
field.set(object, number);
values.add(number);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
break;
case "String":
field.setAccessible(true);
try {
String randomStr = generatingRandomStringAlphabetic();
field.set(object, randomStr);
values.add(randomStr);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
break;
case "LocalDate":
field.setAccessible(true);
LocalDate localDate = generatorLocalDate(yearMin, yearMax);
try {
field.set(object, localDate);
values.add(localDate);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
break;
case "LocalDateTime":
field.setAccessible(true);
LocalDateTime localDateTime = generatorLocalDateTime(yearMin, yearMax);
try {
field.set(object, localDateTime);
values.add(localDateTime);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
break;
case "Character":
field.setAccessible(true);
Character character = generateRandomSpecialCharacters();
try {
field.set(object, character);
values.add(character);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
break;
default:
LOGGER.error(LOGGER_MESSAGE_DATA_TYPE);
}
}
}
这段代码,当它遇到一个分为几个类的对象时,只能看到后代类的字段。
可以在代码中更正什么,以便Field[] 字段数组
Field[] fields = objectClass.getDeclaredFields();
得到所有字段,包括祖先类的字段
如此决定
private static <S> void obtainMetadataOfObject(S object, List<Object> values) {
Class<?> objectClass = object.getClass();
Field[] fields;
Class superClazz = objectClass.getSuperclass();
String nameObjectClass = "Object";
String simpleNameObjectExpected = superClazz.getSimpleName();
boolean isObjectClass = Objects.equals(simpleNameObjectExpected, nameObjectClass);
if(!isObjectClass){
List<Field> allFields = getAllFields(objectClass);
fields = convertCollectionToArray(allFields);
} else {
fields = objectClass.getDeclaredFields();
}
compareLengthArrays(fields.length, values.size());
parseArrFields(fields, object, values);
}
/**
* Обработка полей составного класса, используется рефлексия
* @param clazz - тип объекта
* @return - возвращает список полей составного класса
*/
private static List<Field> getAllFields(Class clazz) {
List<Field> fields = Arrays.asList(clazz.getDeclaredFields());
List<Field> fieldList = new ArrayList<>(fields);
Class superClazz = clazz.getSuperclass();
if(superClazz != null){
fieldList.addAll(getAllFields(superClazz));
}
return fieldList ;
}
/** Преобразование коллекции в массив
* Field[]::new - указывает на то, что каждый элемент коллекции нужно
* передать в конструктор класса Field и после создания экземпляра, данный экземпляр
* добавляется в указанный тип массива*/
private static Field[] convertCollectionToArray(List<Field> fields){
Stream<Field> fieldStream = fields.stream();
return fieldStream.toArray(Field[]::new);
}
递归遍历
objectClass.getSuperclass()阵列粘合不是最佳的;)