diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderBigDecimal.java b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderBigDecimal.java index 821698d632..a138702806 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderBigDecimal.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderBigDecimal.java @@ -10,7 +10,7 @@ import java.util.function.BiConsumer; final class FieldReaderBigDecimal - extends FieldReader { + extends FieldReaderBoxedType { public FieldReaderBigDecimal( String fieldName, Class fieldClass, @@ -24,32 +24,11 @@ public FieldReaderBigDecimal( Field field, BiConsumer function ) { - super(fieldName, fieldClass, fieldClass, ordinal, features, format, locale, defaultValue, schema, method, field, function, null, null); + super(fieldName, fieldClass, ordinal, features, format, locale, defaultValue, schema, method, field, function, null, null); } @Override - public void accept(T object, Object value) { - propertyAccessor.setObject(object, value); - } - - @Override - public void readFieldValue(JSONReader jsonReader, T object) { - BigDecimal fieldValue; - try { - fieldValue = jsonReader.readBigDecimal(); - } catch (Exception e) { - if ((jsonReader.features(this.features) & JSONReader.Feature.NullOnError.mask) != 0) { - fieldValue = null; - } else { - throw e; - } - } - - propertyAccessor.setObject(object, fieldValue); - } - - @Override - public Object readFieldValue(JSONReader jsonReader) { + protected BigDecimal readValue(JSONReader jsonReader) { return jsonReader.readBigDecimal(); } } diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderBool.java b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderBool.java index 8ed439526c..c05c81ddb3 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderBool.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderBool.java @@ -11,7 +11,7 @@ import java.util.function.BiConsumer; final class FieldReaderBool - extends FieldReader { + extends FieldReaderBoxedType { public FieldReaderBool( String fieldName, Class fieldClass, @@ -27,33 +27,22 @@ public FieldReaderBool( String paramName, Parameter parameter ) { - super(fieldName, fieldClass, fieldClass, ordinal, features, format, locale, defaultValue, schema, method, field, function, paramName, parameter); + super(fieldName, fieldClass, ordinal, features, format, locale, defaultValue, schema, method, field, function, paramName, parameter); } @Override public void accept(T object, Object value) { - propertyAccessor.setObject(object, - TypeUtils.toBoolean(value)); - } + Boolean boolValue = TypeUtils.toBoolean(value); - @Override - public void readFieldValue(JSONReader jsonReader, T object) { - Boolean fieldValue; - try { - fieldValue = jsonReader.readBool(); - } catch (Exception e) { - if ((jsonReader.features(this.features) & JSONReader.Feature.NullOnError.mask) != 0) { - fieldValue = null; - } else { - throw e; - } + if (schema != null) { + schema.assertValidate(boolValue); } - propertyAccessor.setObject(object, fieldValue); + propertyAccessor.setObject(object, boolValue); } @Override - public Object readFieldValue(JSONReader jsonReader) { + protected Boolean readValue(JSONReader jsonReader) { return jsonReader.readBool(); } } diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderBoxedType.java b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderBoxedType.java new file mode 100644 index 0000000000..452af8d581 --- /dev/null +++ b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderBoxedType.java @@ -0,0 +1,79 @@ +package com.alibaba.fastjson2.reader; + +import com.alibaba.fastjson2.JSONReader; +import com.alibaba.fastjson2.schema.JSONSchema; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.util.Locale; +import java.util.function.BiConsumer; + +/** + * Abstract base class for boxed type field readers (Integer, Long, Double, Float, Boolean, etc.). + * Consolidates common error handling and schema validation logic. + * + * @param the object type containing the field + * @param the field value type + */ +abstract class FieldReaderBoxedType extends FieldReader { + FieldReaderBoxedType( + String fieldName, + Class fieldClass, + int ordinal, + long features, + String format, + Locale locale, + Object defaultValue, + JSONSchema schema, + Method method, + Field field, + BiConsumer function, + String paramName, + Parameter parameter + ) { + super(fieldName, fieldClass, fieldClass, ordinal, features, format, locale, defaultValue, schema, method, field, function, paramName, parameter); + } + + @Override + public void accept(T object, Object value) { + if (schema != null) { + schema.assertValidate(value); + } + propertyAccessor.setObject(object, value); + } + + @Override + public void readFieldValue(JSONReader jsonReader, T object) { + V value; + try { + value = readValue(jsonReader); + } catch (Exception e) { + if ((jsonReader.features(this.features) & JSONReader.Feature.NullOnError.mask) != 0) { + value = null; + } else { + throw e; + } + } + + if (schema != null) { + schema.assertValidate(value); + } + + propertyAccessor.setObject(object, value); + } + + @Override + public Object readFieldValue(JSONReader jsonReader) { + return readValue(jsonReader); + } + + /** + * Read the specific value type from JSONReader. + * Subclasses must implement this to call the appropriate reader method. + * + * @param jsonReader the JSON reader + * @return the read value + */ + protected abstract V readValue(JSONReader jsonReader); +} diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderDouble.java b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderDouble.java index 2b80047789..d229fc607e 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderDouble.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderDouble.java @@ -10,7 +10,7 @@ import java.util.function.BiConsumer; final class FieldReaderDouble - extends FieldReader { + extends FieldReaderBoxedType { FieldReaderDouble( String fieldName, Class fieldClass, @@ -26,19 +26,14 @@ final class FieldReaderDouble String paramName, Parameter parameter ) { - super(fieldName, fieldClass, fieldClass, ordinal, features, format, locale, defaultValue, schema, method, field, function, paramName, parameter); - } - - @Override - public void accept(T object, Object value) { - propertyAccessor.setObject(object, value); + super(fieldName, fieldClass, ordinal, features, format, locale, defaultValue, schema, method, field, function, paramName, parameter); } @Override public void readFieldValue(JSONReader jsonReader, T object) { Double value; try { - value = jsonReader.readDouble(); + value = readValue(jsonReader); } catch (Exception e) { if ((jsonReader.features(this.features) & JSONReader.Feature.NullOnError.mask) != 0) { value = null; @@ -51,11 +46,15 @@ public void readFieldValue(JSONReader jsonReader, T object) { return; } + if (schema != null) { + schema.assertValidate(value); + } + propertyAccessor.setObject(object, value); } @Override - public Object readFieldValue(JSONReader jsonReader) { + protected Double readValue(JSONReader jsonReader) { return jsonReader.readDouble(); } } diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderFloat.java b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderFloat.java index c4bbb622c4..99f3278dce 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderFloat.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderFloat.java @@ -10,7 +10,7 @@ import java.util.function.BiConsumer; final class FieldReaderFloat - extends FieldReader { + extends FieldReaderBoxedType { FieldReaderFloat( String fieldName, Class fieldClass, @@ -26,32 +26,11 @@ final class FieldReaderFloat String paramName, Parameter parameter ) { - super(fieldName, fieldClass, fieldClass, ordinal, features, format, locale, defaultValue, schema, method, field, function, paramName, parameter); + super(fieldName, fieldClass, ordinal, features, format, locale, defaultValue, schema, method, field, function, paramName, parameter); } @Override - public void accept(T object, Object value) { - propertyAccessor.setObject(object, value); - } - - @Override - public void readFieldValue(JSONReader jsonReader, T object) { - Float value; - try { - value = jsonReader.readFloat(); - } catch (Exception e) { - if ((jsonReader.features(this.features) & JSONReader.Feature.NullOnError.mask) != 0) { - value = null; - } else { - throw e; - } - } - - propertyAccessor.setObject(object, value); - } - - @Override - public Object readFieldValue(JSONReader jsonReader) { + protected Float readValue(JSONReader jsonReader) { return jsonReader.readFloat(); } } diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderInt16.java b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderInt16.java index 2e5cf56a25..852c2f7a72 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderInt16.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderInt16.java @@ -10,7 +10,7 @@ import java.util.function.BiConsumer; final class FieldReaderInt16 - extends FieldReader { + extends FieldReaderBoxedType { FieldReaderInt16( String fieldName, Class fieldClass, @@ -26,33 +26,12 @@ final class FieldReaderInt16 String paramName, Parameter parameter ) { - super(fieldName, fieldClass, fieldClass, ordinal, features, format, locale, defaultValue, schema, method, field, function, paramName, parameter); + super(fieldName, fieldClass, ordinal, features, format, locale, defaultValue, schema, method, field, function, paramName, parameter); } @Override - public void accept(T object, Object value) { - propertyAccessor.setObject(object, value); - } - - @Override - public void readFieldValue(JSONReader jsonReader, T object) { - Short value; - try { - Integer intValue = jsonReader.readInt32(); - value = intValue == null ? null : intValue.shortValue(); - } catch (Exception e) { - if ((jsonReader.features(this.features) & JSONReader.Feature.NullOnError.mask) != 0) { - value = null; - } else { - throw e; - } - } - - propertyAccessor.setObject(object, value); - } - - @Override - public Object readFieldValue(JSONReader jsonReader) { - return jsonReader.readInt32(); + protected Short readValue(JSONReader jsonReader) { + Integer intValue = jsonReader.readInt32(); + return intValue == null ? null : intValue.shortValue(); } } diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderInt32.java b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderInt32.java index 6c68c2e004..78997db90e 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderInt32.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderInt32.java @@ -10,7 +10,7 @@ import java.util.function.BiConsumer; final class FieldReaderInt32 - extends FieldReader { + extends FieldReaderBoxedType { FieldReaderInt32( String fieldName, Class fieldClass, @@ -26,32 +26,11 @@ final class FieldReaderInt32 String paramName, Parameter parameter ) { - super(fieldName, fieldClass, fieldClass, ordinal, features, format, locale, defaultValue, schema, method, field, function, paramName, parameter); + super(fieldName, fieldClass, ordinal, features, format, locale, defaultValue, schema, method, field, function, paramName, parameter); } @Override - public void accept(T object, Object value) { - propertyAccessor.setObject(object, value); - } - - @Override - public void readFieldValue(JSONReader jsonReader, T object) { - Integer value; - try { - value = jsonReader.readInt32(); - } catch (Exception e) { - if ((jsonReader.features(this.features) & JSONReader.Feature.NullOnError.mask) != 0) { - value = null; - } else { - throw e; - } - } - - propertyAccessor.setObject(object, value); - } - - @Override - public Object readFieldValue(JSONReader jsonReader) { + protected Integer readValue(JSONReader jsonReader) { return jsonReader.readInt32(); } } diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderInt64.java b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderInt64.java index 15c02beb4c..a33c01c36d 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderInt64.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderInt64.java @@ -11,7 +11,7 @@ import java.util.function.BiConsumer; final class FieldReaderInt64 - extends FieldReader { + extends FieldReaderBoxedType { FieldReaderInt64( String fieldName, Class fieldClass, @@ -27,11 +27,14 @@ final class FieldReaderInt64 String paramName, Parameter parameter ) { - super(fieldName, fieldClass, fieldClass, ordinal, features, format, locale, defaultValue, schema, method, field, function, paramName, parameter); + super(fieldName, fieldClass, ordinal, features, format, locale, defaultValue, schema, method, field, function, paramName, parameter); } @Override public void accept(T object, Object value) { + // Convert to Long for schema validation, but set original value + // This preserves the original behavior where validation used converted value + // but the original value was set (to preserve type information) Long longValue = TypeUtils.toLong(value); if (schema != null) { @@ -42,27 +45,7 @@ public void accept(T object, Object value) { } @Override - public void readFieldValue(JSONReader jsonReader, T object) { - Long value; - try { - value = jsonReader.readInt64(); - } catch (Exception e) { - if ((jsonReader.features(this.features) & JSONReader.Feature.NullOnError.mask) != 0) { - value = null; - } else { - throw e; - } - } - - if (schema != null) { - schema.assertValidate(value); - } - - propertyAccessor.setObject(object, value); - } - - @Override - public Object readFieldValue(JSONReader jsonReader) { + protected Long readValue(JSONReader jsonReader) { return jsonReader.readInt64(); } } diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderInt8.java b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderInt8.java index 5fcd59d0b0..407f98a235 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderInt8.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderInt8.java @@ -10,7 +10,7 @@ import java.util.function.BiConsumer; final class FieldReaderInt8 - extends FieldReader { + extends FieldReaderBoxedType { FieldReaderInt8( String fieldName, Class fieldClass, @@ -26,33 +26,12 @@ final class FieldReaderInt8 String paramName, Parameter parameter ) { - super(fieldName, fieldClass, fieldClass, ordinal, features, format, locale, defaultValue, schema, method, field, function, paramName, parameter); + super(fieldName, fieldClass, ordinal, features, format, locale, defaultValue, schema, method, field, function, paramName, parameter); } @Override - public void accept(T object, Object value) { - propertyAccessor.setObject(object, value); - } - - @Override - public void readFieldValue(JSONReader jsonReader, T object) { - Byte value; - try { - Integer intValue = jsonReader.readInt32(); - value = intValue == null ? null : intValue.byteValue(); - } catch (Exception e) { - if ((jsonReader.features(this.features) & JSONReader.Feature.NullOnError.mask) != 0) { - value = null; - } else { - throw e; - } - } - - propertyAccessor.setObject(object, value); - } - - @Override - public Object readFieldValue(JSONReader jsonReader) { - return jsonReader.readInt32(); + protected Byte readValue(JSONReader jsonReader) { + Integer intValue = jsonReader.readInt32(); + return intValue == null ? null : intValue.byteValue(); } }