in core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderCreator.java [2293:2661]
public <T> FieldReader createFieldReaderMethod(
Class<T> objectClass,
Type objectType,
String fieldName,
int ordinal,
long features,
String format,
Locale locale,
Object defaultValue,
String schema,
Type fieldType,
Class fieldClass,
Method method,
ObjectReader initReader,
String keyName,
BiConsumer arrayToMapDuplicateHandler
) {
if (method != null) {
method.setAccessible(true);
}
if (defaultValue instanceof String && fieldClass.isEnum()) {
defaultValue = Enum.valueOf(fieldClass, (String) defaultValue);
}
if (defaultValue != null && defaultValue.getClass() != fieldClass) {
Function typeConvert = JSONFactory
.getDefaultObjectReaderProvider()
.getTypeConvert(defaultValue.getClass(), fieldType);
if (typeConvert != null) {
defaultValue = typeConvert.apply(defaultValue);
} else {
throw new JSONException("illegal defaultValue : " + defaultValue + ", class " + fieldClass.getName());
}
}
JSONSchema jsonSchema = null;
if (schema != null && !schema.isEmpty()) {
JSONObject object = JSON.parseObject(schema);
if (!object.isEmpty()) {
jsonSchema = JSONSchema.of(object, fieldClass);
}
}
if (initReader != null) {
FieldReaderObject fieldReaderObjectMethod = new FieldReaderObject(
fieldName,
fieldType,
fieldClass,
ordinal,
features | FieldInfo.READ_USING_MASK,
format,
locale,
defaultValue,
jsonSchema,
method,
null,
null
);
fieldReaderObjectMethod.initReader = initReader;
return fieldReaderObjectMethod;
}
if (fieldType == boolean.class) {
return new FieldReaderBoolValueMethod(fieldName, ordinal, features, format, (Boolean) defaultValue, jsonSchema, method);
}
if (fieldType == Boolean.class) {
return new FieldReaderBoolMethod(fieldName, fieldType, fieldClass, ordinal, features, format, locale, (Boolean) defaultValue, jsonSchema, method);
}
if (fieldType == byte.class) {
return new FieldReaderInt8ValueMethod(fieldName, fieldType, fieldClass, ordinal, features, format, locale, (Byte) defaultValue, jsonSchema, method);
}
if (fieldType == short.class) {
return new FieldReaderInt16ValueMethod(fieldName, fieldType, fieldClass, ordinal, features, format, locale, (Short) defaultValue, jsonSchema, method);
}
if (fieldType == int.class) {
return new FieldReaderInt32ValueMethod(fieldName, fieldType, fieldClass, ordinal, features, format, (Integer) defaultValue, jsonSchema, method);
}
if (fieldType == long.class) {
return new FieldReaderInt64ValueMethod(fieldName, fieldType, fieldClass, ordinal, features, format, locale, (Long) defaultValue, jsonSchema, method);
}
if (fieldType == float.class) {
return new FieldReaderFloatValueMethod(fieldName, fieldType, fieldClass, ordinal, features, format, locale, (Float) defaultValue, jsonSchema, method);
}
if (fieldType == double.class) {
return new FieldReaderDoubleValueMethod(fieldName, fieldType, fieldClass, ordinal, features, format, locale, (Double) defaultValue, jsonSchema, method);
}
if (fieldType == Byte.class) {
return new FieldReaderInt8Method(fieldName, fieldType, fieldClass, ordinal, features, format, locale, (Byte) defaultValue, jsonSchema, method);
}
if (fieldType == Short.class) {
return new FieldReaderInt16Method(fieldName, fieldType, fieldClass, ordinal, features, format, locale, (Short) defaultValue, jsonSchema, method);
}
if (fieldType == Integer.class) {
return new FieldReaderInt32Method(fieldName, ordinal, features, format, locale, (Integer) defaultValue, jsonSchema, method);
}
if (fieldType == Long.class) {
return new FieldReaderInt64Method(fieldName, ordinal, features, format, locale, (Long) defaultValue, jsonSchema, method);
}
if (fieldType == Float.class) {
return new FieldReaderFloatMethod(fieldName, ordinal, features, format, locale, (Float) defaultValue, jsonSchema, method);
}
if (fieldType == Double.class) {
return new FieldReaderDoubleMethod(fieldName, ordinal, features, format, (Double) defaultValue, jsonSchema, method);
}
if (fieldClass == BigDecimal.class) {
return new FieldReaderBigDecimalMethod(fieldName, fieldType, fieldClass, ordinal, features, format, locale, (BigDecimal) defaultValue, jsonSchema, method);
}
if (fieldClass == BigInteger.class) {
return new FieldReaderBigIntegerMethod(fieldName, fieldType, fieldClass, ordinal, features, format, locale, (BigInteger) defaultValue, jsonSchema, method);
}
if (fieldType == String.class) {
return new FieldReaderStringMethod(fieldName, fieldType, fieldClass, ordinal, features, format, locale, (String) defaultValue, jsonSchema, method);
}
if (fieldType == LocalDate.class) {
return new FieldReaderLocalDate(
fieldName,
fieldType,
fieldClass,
ordinal,
features,
format,
locale,
defaultValue,
jsonSchema,
method,
null,
null
);
}
if (fieldType == OffsetDateTime.class) {
return new FieldReaderOffsetDateTime(
fieldName,
fieldType,
fieldClass,
ordinal,
features,
format,
locale,
defaultValue,
jsonSchema,
method,
null,
null
);
}
if (fieldType == UUID.class) {
return new FieldReaderUUID(
fieldName,
fieldType,
fieldClass,
ordinal,
features,
format,
locale,
defaultValue,
jsonSchema,
method,
null,
null
);
}
if (fieldType == String[].class) {
return new FieldReaderStringArray(
fieldName,
fieldType,
fieldClass,
ordinal,
features,
format,
locale,
defaultValue,
jsonSchema,
method,
null,
null
);
}
Type fieldTypeResolved = null;
Class fieldClassResolved = null;
if (!(fieldType instanceof Class) || !(objectType instanceof Class)) {
fieldTypeResolved = BeanUtils.getFieldType(TypeReference.get(objectType), objectClass, method, fieldType);
fieldClassResolved = TypeUtils.getMapping(fieldTypeResolved);
}
if (method.getParameterCount() == 0) {
if (fieldClass == AtomicInteger.class) {
return new FieldReaderAtomicIntegerMethodReadOnly(fieldName, fieldClass, ordinal, jsonSchema, method);
}
if (fieldClass == AtomicLong.class) {
return new FieldReaderAtomicLongReadOnly(fieldName, fieldClass, ordinal, jsonSchema, method);
}
if (fieldClass == AtomicIntegerArray.class) {
return new FieldReaderAtomicIntegerArrayReadOnly(fieldName, fieldClass, ordinal, jsonSchema, method);
}
if (fieldClass == AtomicLongArray.class) {
return new FieldReaderAtomicLongArrayReadOnly(fieldName, fieldClass, ordinal, jsonSchema, method);
}
if (fieldClass == AtomicBoolean.class) {
return new FieldReaderAtomicBooleanMethodReadOnly(fieldName, fieldClass, ordinal, jsonSchema, method);
}
if (fieldClass == AtomicReference.class) {
return new FieldReaderAtomicReferenceMethodReadOnly(fieldName, fieldType, fieldClass, ordinal, jsonSchema, method);
}
if (Collection.class.isAssignableFrom(fieldClass)) {
Field field = null;
String methodName = method.getName();
if (methodName.startsWith("get")) {
String getterName = BeanUtils.getterName(methodName, PropertyNamingStrategy.CamelCase.name());
field = BeanUtils.getDeclaredField(method.getDeclaringClass(), getterName);
}
return new FieldReaderCollectionMethodReadOnly(
fieldName,
fieldTypeResolved != null ? fieldTypeResolved : fieldType,
fieldClass,
ordinal,
features,
format,
jsonSchema,
method,
field
);
}
if (Map.class.isAssignableFrom(fieldClass)) {
Field field = null;
String methodName = method.getName();
if (methodName.startsWith("get")) {
String getterName = BeanUtils.getterName(methodName, PropertyNamingStrategy.CamelCase.name());
field = BeanUtils.getDeclaredField(method.getDeclaringClass(), getterName);
}
return new FieldReaderMapMethodReadOnly(
fieldName,
fieldType,
fieldClass,
ordinal,
features,
format,
jsonSchema,
method,
field,
keyName,
arrayToMapDuplicateHandler
);
}
if (!objectClass.isInterface()) {
return null;
}
}
boolean list = fieldClass == List.class
|| fieldClass == ArrayList.class
|| fieldClass == LinkedList.class
|| "cn.hutool.json.JSONArray".equals(fieldClass.getName());
if (list) {
if (fieldTypeResolved instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) fieldTypeResolved;
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
if (actualTypeArguments.length == 1) {
Type itemType = actualTypeArguments[0];
Class itemClass = TypeUtils.getMapping(itemType);
if (itemClass == String.class) {
return new FieldReaderList(fieldName, fieldTypeResolved, fieldClass, String.class, String.class, ordinal, features, format, locale, null, jsonSchema, method, null, null);
}
return new FieldReaderList(fieldName, fieldTypeResolved, fieldClassResolved, itemType, itemClass, ordinal, features, format, locale, null, jsonSchema, method, null, null);
}
}
return new FieldReaderList(fieldName, fieldType, fieldClass, Object.class, Object.class, ordinal, features, format, locale, null, jsonSchema, method, null, null);
}
if (fieldClass == Date.class) {
return new FieldReaderDate(fieldName, fieldType, fieldClass, ordinal, features, format, locale, defaultValue, jsonSchema, null, method, null);
}
if (fieldClass == StackTraceElement[].class && method.getDeclaringClass() == Throwable.class) {
return new FieldReaderStackTrace(
fieldName,
fieldTypeResolved != null ? fieldTypeResolved : fieldType,
fieldClass,
ordinal,
features,
format,
locale,
defaultValue,
jsonSchema,
method,
null,
(BiConsumer<Throwable, StackTraceElement[]>) Throwable::setStackTrace
);
}
Field field = null;
if ((features & FieldInfo.UNWRAPPED_MASK) != 0) {
String methodName = method.getName();
if (methodName.startsWith("set")) {
String setterName = BeanUtils.setterName(methodName, PropertyNamingStrategy.CamelCase.name());
field = BeanUtils.getDeclaredField(method.getDeclaringClass(), setterName);
try {
field.setAccessible(true);
} catch (Throwable ignored) {
// ignored
}
}
}
if (Map.class.isAssignableFrom(fieldClass)) {
return new FieldReaderMapMethod(
fieldName,
fieldTypeResolved != null ? fieldTypeResolved : fieldType,
fieldClass,
ordinal,
features,
format,
locale,
defaultValue,
jsonSchema,
method,
field,
null,
keyName,
arrayToMapDuplicateHandler
);
}
return new FieldReaderObject(
fieldName,
fieldTypeResolved != null ? fieldTypeResolved : fieldType,
fieldClass,
ordinal,
features,
format,
locale,
defaultValue,
jsonSchema,
method,
field,
null
);
}