@@ -157,111 +157,6 @@ public JSONObject() {
157157 this .map = new HashMap <String , Object >();
158158 }
159159
160- /**
161- * A mapping from Java classes to functions that convert a generic {@code Object}
162- * into an instance of the target class.
163- *
164- * <p>Examples of default mappings:
165- * <ul>
166- * <li>{@code int.class} or {@code Integer.class} -> Converts a {@code Number} to {@code int}</li>
167- * <li>{@code boolean.class} or {@code Boolean.class} -> Identity function</li>
168- * <li>{@code String.class} -> Identity function</li>
169- * </ul>
170- */
171- private static final Map <Class <?>, TypeConverter <?>> classMapping = new HashMap <Class <?>, TypeConverter <?>>();
172-
173- /**
174- * A mapping from collection interface types to suppliers that produce
175- * instances of concrete collection implementations.
176- *
177- */
178- private static final Map <Class <?>, InstanceCreator <?>> collectionMapping = new HashMap <Class <?>, InstanceCreator <?>>();
179-
180- // Static initializer block to populate default mappings
181- static {
182- classMapping .put (int .class , new TypeConverter <Integer >() {
183- public Integer convert (Object input ) {
184- return ((Number ) input ).intValue ();
185- }
186- });
187- classMapping .put (Integer .class , new TypeConverter <Integer >() {
188- public Integer convert (Object input ) {
189- return ((Number ) input ).intValue ();
190- }
191- });
192- classMapping .put (double .class , new TypeConverter <Double >() {
193- public Double convert (Object input ) {
194- return ((Number ) input ).doubleValue ();
195- }
196- });
197- classMapping .put (Double .class , new TypeConverter <Double >() {
198- public Double convert (Object input ) {
199- return ((Number ) input ).doubleValue ();
200- }
201- });
202- classMapping .put (float .class , new TypeConverter <Float >() {
203- public Float convert (Object input ) {
204- return ((Number ) input ).floatValue ();
205- }
206- });
207- classMapping .put (Float .class , new TypeConverter <Float >() {
208- public Float convert (Object input ) {
209- return ((Number ) input ).floatValue ();
210- }
211- });
212- classMapping .put (long .class , new TypeConverter <Long >() {
213- public Long convert (Object input ) {
214- return ((Number ) input ).longValue ();
215- }
216- });
217- classMapping .put (Long .class , new TypeConverter <Long >() {
218- public Long convert (Object input ) {
219- return ((Number ) input ).longValue ();
220- }
221- });
222- classMapping .put (boolean .class , new TypeConverter <Boolean >() {
223- public Boolean convert (Object input ) {
224- return (Boolean ) input ;
225- }
226- });
227- classMapping .put (Boolean .class , new TypeConverter <Boolean >() {
228- public Boolean convert (Object input ) {
229- return (Boolean ) input ;
230- }
231- });
232- classMapping .put (String .class , new TypeConverter <String >() {
233- public String convert (Object input ) {
234- return (String ) input ;
235- }
236- });
237- classMapping .put (BigDecimal .class , new TypeConverter <BigDecimal >() {
238- public BigDecimal convert (Object input ) {
239- return new BigDecimal ((String ) input );
240- }
241- });
242- classMapping .put (BigInteger .class , new TypeConverter <BigInteger >() {
243- public BigInteger convert (Object input ) {
244- return new BigInteger ((String ) input );
245- }
246- });
247-
248- collectionMapping .put (List .class , new InstanceCreator <List >() {
249- public List create () {
250- return new ArrayList ();
251- }
252- });
253- collectionMapping .put (Set .class , new InstanceCreator <Set >() {
254- public Set create () {
255- return new HashSet ();
256- }
257- });
258- collectionMapping .put (Map .class , new InstanceCreator <Map >() {
259- public Map create () {
260- return new HashMap ();
261- }
262- });
263- }
264-
265160 /**
266161 * Construct a JSONObject from a subset of another JSONObject. An array of
267162 * strings is used to identify the keys that should be copied. Missing keys
@@ -3359,8 +3254,8 @@ private Type[] getMapTypes(Type type) {
33593254 *
33603255 * <p>This method attempts to map JSON key-value pairs to the corresponding fields
33613256 * of the given class. It supports basic data types including int, double, float,
3362- * long, and boolean (as well as their boxed counterparts). The class must have a
3363- * no-argument constructor, and the field names in the class must match the keys
3257+ * long, and boolean (as well as their boxed counterparts). The class must have a
3258+ * no-argument constructor, and the field names in the class must match the keys
33643259 * in the JSON string.
33653260 *
33663261 * @param jsonString json in string format
@@ -3402,12 +3297,8 @@ public <T> T fromJson(Class<T> clazz) {
34023297 Object value = get (fieldName );
34033298 Type fieldType = field .getGenericType ();
34043299 Class <?> rawType = getRawType (fieldType );
3405- if (classMapping .containsKey (rawType )) {
3406- field .set (obj , classMapping .get (rawType ).convert (value ));
3407- } else {
3408- Object convertedValue = convertValue (value , fieldType );
3409- field .set (obj , convertedValue );
3410- }
3300+ Object convertedValue = convertValue (value , fieldType );
3301+ field .set (obj , convertedValue );
34113302 }
34123303 }
34133304 return obj ;
@@ -3433,9 +3324,22 @@ private Object convertValue(Object value, Type targetType) throws JSONException
34333324 return value ;
34343325 }
34353326
3436- // Use registered type converter
3437- if (classMapping .containsKey (rawType )) {
3438- return classMapping .get (rawType ).convert (value );
3327+ if (rawType == int .class || rawType == Integer .class ) {
3328+ return ((Number ) value ).intValue ();
3329+ } else if (rawType == double .class || rawType == Double .class ) {
3330+ return ((Number ) value ).doubleValue ();
3331+ } else if (rawType == float .class || rawType == Float .class ) {
3332+ return ((Number ) value ).floatValue ();
3333+ } else if (rawType == long .class || rawType == Long .class ) {
3334+ return ((Number ) value ).longValue ();
3335+ } else if (rawType == boolean .class || rawType == Boolean .class ) {
3336+ return (Boolean ) value ;
3337+ } else if (rawType == String .class ) {
3338+ return (String ) value ;
3339+ } else if (rawType == BigDecimal .class ) {
3340+ return new BigDecimal ((String ) value );
3341+ } else if (rawType == BigInteger .class ) {
3342+ return new BigInteger ((String ) value );
34393343 }
34403344
34413345 // Enum conversion
@@ -3473,13 +3377,8 @@ else if (!rawType.isPrimitive() && !rawType.isEnum() && value instanceof JSONObj
34733377 */
34743378 private Map <?, ?> convertToMap (JSONObject jsonMap , Type keyType , Type valueType , Class <?> mapType ) throws JSONException {
34753379 try {
3476- InstanceCreator <?> creator = collectionMapping .get (mapType ) != null ? collectionMapping .get (mapType ) : new InstanceCreator <Map >() {
3477- public Map create () {
3478- return new HashMap ();
3479- }
3480- };
34813380 @ SuppressWarnings ("unchecked" )
3482- Map <Object , Object > createdMap = ( Map < Object , Object >) creator . create ();
3381+ Map <Object , Object > createdMap = new HashMap ();
34833382
34843383 for (Object keyObj : jsonMap .keySet ()) {
34853384 String keyStr = (String ) keyObj ;
@@ -3517,12 +3416,7 @@ private <E> E stringToEnum(Class<?> enumClass, String value) throws JSONExceptio
35173416 @ SuppressWarnings ("unchecked" )
35183417 private <T > Collection <T > fromJsonArray (JSONArray jsonArray , Class <?> collectionType , Type elementType ) throws JSONException {
35193418 try {
3520- InstanceCreator <?> creator = collectionMapping .get (collectionType ) != null ? collectionMapping .get (collectionType ) : new InstanceCreator <List >() {
3521- public List create () {
3522- return new ArrayList ();
3523- }
3524- };
3525- Collection <T > collection = (Collection <T >) creator .create ();
3419+ Collection <T > collection = getCollection (collectionType );
35263420
35273421 for (int i = 0 ; i < jsonArray .length (); i ++) {
35283422 Object jsonElement = jsonArray .get (i );
@@ -3536,4 +3430,31 @@ public List create() {
35363430 }
35373431 }
35383432
3433+ /**
3434+ * Creates and returns a new instance of a supported {@link Collection} implementation
3435+ * based on the specified collection type.
3436+ * <p>
3437+ * This method currently supports the following collection types:
3438+ * <ul>
3439+ * <li>{@code List.class}</li>
3440+ * <li>{@code ArrayList.class}</li>
3441+ * <li>{@code Set.class}</li>
3442+ * <li>{@code HashSet.class}</li>
3443+ * </ul>
3444+ * If the provided type does not match any of the supported types, a {@link JSONException}
3445+ * is thrown.
3446+ *
3447+ * @param collectionType the {@link Class} object representing the desired collection type
3448+ * @return a new empty instance of the specified collection type
3449+ * @throws JSONException if the specified type is not a supported collection type
3450+ */
3451+ private Collection getCollection (Class <?> collectionType ) throws JSONException {
3452+ if (collectionType == List .class || collectionType == ArrayList .class ) {
3453+ return new ArrayList <>();
3454+ } else if (collectionType == Set .class || collectionType == HashSet .class ) {
3455+ return new HashSet <>();
3456+ } else {
3457+ throw new JSONException ("Unsupported Collection type: " + collectionType .getName ());
3458+ }
3459+ }
35393460}
0 commit comments