@@ -103,24 +103,14 @@ public <T> ObjectConstructor<T> get(TypeToken<T> typeToken) {
103
103
@ SuppressWarnings ("unchecked" ) // types must agree
104
104
InstanceCreator <T > typeCreator = (InstanceCreator <T >) instanceCreators .get (type );
105
105
if (typeCreator != null ) {
106
- return new ObjectConstructor <T >() {
107
- @ Override
108
- public T construct () {
109
- return typeCreator .createInstance (type );
110
- }
111
- };
106
+ return () -> typeCreator .createInstance (type );
112
107
}
113
108
114
109
// Next try raw type match for instance creators
115
110
@ SuppressWarnings ("unchecked" ) // types must agree
116
111
InstanceCreator <T > rawTypeCreator = (InstanceCreator <T >) instanceCreators .get (rawType );
117
112
if (rawTypeCreator != null ) {
118
- return new ObjectConstructor <T >() {
119
- @ Override
120
- public T construct () {
121
- return rawTypeCreator .createInstance (type );
122
- }
123
- };
113
+ return () -> rawTypeCreator .createInstance (type );
124
114
}
125
115
126
116
// First consider special constructors before checking for no-args constructors
@@ -147,11 +137,8 @@ public T construct() {
147
137
// of adjusting filter suggested below is irrelevant since it would not solve the problem
148
138
String exceptionMessage = checkInstantiable (rawType );
149
139
if (exceptionMessage != null ) {
150
- return new ObjectConstructor <T >() {
151
- @ Override
152
- public T construct () {
153
- throw new JsonIOException (exceptionMessage );
154
- }
140
+ return () -> {
141
+ throw new JsonIOException (exceptionMessage );
155
142
};
156
143
}
157
144
@@ -167,11 +154,8 @@ public T construct() {
167
154
+ "; ReflectionAccessFilter does not permit using reflection or Unsafe. Register an"
168
155
+ " InstanceCreator or a TypeAdapter for this type or adjust the access filter to"
169
156
+ " allow using reflection." ;
170
- return new ObjectConstructor <T >() {
171
- @ Override
172
- public T construct () {
173
- throw new JsonIOException (message );
174
- }
157
+ return () -> {
158
+ throw new JsonIOException (message );
175
159
};
176
160
}
177
161
}
@@ -183,42 +167,36 @@ public T construct() {
183
167
private static <T > ObjectConstructor <T > newSpecialCollectionConstructor (
184
168
Type type , Class <? super T > rawType ) {
185
169
if (EnumSet .class .isAssignableFrom (rawType )) {
186
- return new ObjectConstructor <T >() {
187
- @ Override
188
- public T construct () {
189
- if (type instanceof ParameterizedType ) {
190
- Type elementType = ((ParameterizedType ) type ).getActualTypeArguments ()[0 ];
191
- if (elementType instanceof Class ) {
192
- @ SuppressWarnings ({"unchecked" , "rawtypes" })
193
- T set = (T ) EnumSet .noneOf ((Class ) elementType );
194
- return set ;
195
- } else {
196
- throw new JsonIOException ("Invalid EnumSet type: " + type .toString ());
197
- }
170
+ return () -> {
171
+ if (type instanceof ParameterizedType ) {
172
+ Type elementType = ((ParameterizedType ) type ).getActualTypeArguments ()[0 ];
173
+ if (elementType instanceof Class ) {
174
+ @ SuppressWarnings ({"unchecked" , "rawtypes" })
175
+ T set = (T ) EnumSet .noneOf ((Class ) elementType );
176
+ return set ;
198
177
} else {
199
178
throw new JsonIOException ("Invalid EnumSet type: " + type .toString ());
200
179
}
180
+ } else {
181
+ throw new JsonIOException ("Invalid EnumSet type: " + type .toString ());
201
182
}
202
183
};
203
184
}
204
185
// Only support creation of EnumMap, but not of custom subtypes; for them type parameters
205
186
// and constructor parameter might have completely different meaning
206
187
else if (rawType == EnumMap .class ) {
207
- return new ObjectConstructor <T >() {
208
- @ Override
209
- public T construct () {
210
- if (type instanceof ParameterizedType ) {
211
- Type elementType = ((ParameterizedType ) type ).getActualTypeArguments ()[0 ];
212
- if (elementType instanceof Class ) {
213
- @ SuppressWarnings ({"unchecked" , "rawtypes" })
214
- T map = (T ) new EnumMap ((Class ) elementType );
215
- return map ;
216
- } else {
217
- throw new JsonIOException ("Invalid EnumMap type: " + type .toString ());
218
- }
188
+ return () -> {
189
+ if (type instanceof ParameterizedType ) {
190
+ Type elementType = ((ParameterizedType ) type ).getActualTypeArguments ()[0 ];
191
+ if (elementType instanceof Class ) {
192
+ @ SuppressWarnings ({"unchecked" , "rawtypes" })
193
+ T map = (T ) new EnumMap ((Class ) elementType );
194
+ return map ;
219
195
} else {
220
196
throw new JsonIOException ("Invalid EnumMap type: " + type .toString ());
221
197
}
198
+ } else {
199
+ throw new JsonIOException ("Invalid EnumMap type: " + type .toString ());
222
200
}
223
201
};
224
202
}
@@ -256,11 +234,8 @@ private static <T> ObjectConstructor<T> newDefaultConstructor(
256
234
+ " constructor is not accessible and ReflectionAccessFilter does not permit making"
257
235
+ " it accessible. Register an InstanceCreator or a TypeAdapter for this type, change"
258
236
+ " the visibility of the constructor or adjust the access filter." ;
259
- return new ObjectConstructor <T >() {
260
- @ Override
261
- public T construct () {
262
- throw new JsonIOException (message );
263
- }
237
+ return () -> {
238
+ throw new JsonIOException (message );
264
239
};
265
240
}
266
241
@@ -277,45 +252,39 @@ public T construct() {
277
252
* (compared to directly throwing exception here), e.g. when runtime type
278
253
* of object is inaccessible, but compile-time type is accessible.
279
254
*/
280
- return new ObjectConstructor <T >() {
281
- @ Override
282
- public T construct () {
283
- // New exception is created every time to avoid keeping reference
284
- // to exception with potentially long stack trace, causing a
285
- // memory leak
286
- throw new JsonIOException (exceptionMessage );
287
- }
255
+ return () -> {
256
+ // New exception is created every time to avoid keeping reference
257
+ // to exception with potentially long stack trace, causing a
258
+ // memory leak
259
+ throw new JsonIOException (exceptionMessage );
288
260
};
289
261
}
290
262
}
291
263
292
- return new ObjectConstructor <T >() {
293
- @ Override
294
- public T construct () {
295
- try {
296
- @ SuppressWarnings ("unchecked" ) // T is the same raw type as is requested
297
- T newInstance = (T ) constructor .newInstance ();
298
- return newInstance ;
299
- }
300
- // Note: InstantiationException should be impossible because check at start of method made
301
- // sure that class is not abstract
302
- catch (InstantiationException e ) {
303
- throw new RuntimeException (
304
- "Failed to invoke constructor '"
305
- + ReflectionHelper .constructorToString (constructor )
306
- + "' with no args" ,
307
- e );
308
- } catch (InvocationTargetException e ) {
309
- // TODO: don't wrap if cause is unchecked?
310
- // TODO: JsonParseException ?
311
- throw new RuntimeException (
312
- "Failed to invoke constructor '"
313
- + ReflectionHelper .constructorToString (constructor )
314
- + "' with no args" ,
315
- e .getCause ());
316
- } catch (IllegalAccessException e ) {
317
- throw ReflectionHelper .createExceptionForUnexpectedIllegalAccess (e );
318
- }
264
+ return () -> {
265
+ try {
266
+ @ SuppressWarnings ("unchecked" ) // T is the same raw type as is requested
267
+ T newInstance = (T ) constructor .newInstance ();
268
+ return newInstance ;
269
+ }
270
+ // Note: InstantiationException should be impossible because check at start of method made
271
+ // sure that class is not abstract
272
+ catch (InstantiationException e ) {
273
+ throw new RuntimeException (
274
+ "Failed to invoke constructor '"
275
+ + ReflectionHelper .constructorToString (constructor )
276
+ + "' with no args" ,
277
+ e );
278
+ } catch (InvocationTargetException e ) {
279
+ // TODO: don't wrap if cause is unchecked?
280
+ // TODO: JsonParseException ?
281
+ throw new RuntimeException (
282
+ "Failed to invoke constructor '"
283
+ + ReflectionHelper .constructorToString (constructor )
284
+ + "' with no args" ,
285
+ e .getCause ());
286
+ } catch (IllegalAccessException e ) {
287
+ throw ReflectionHelper .createExceptionForUnexpectedIllegalAccess (e );
319
288
}
320
289
};
321
290
}
@@ -335,74 +304,29 @@ private static <T> ObjectConstructor<T> newDefaultImplementationConstructor(
335
304
336
305
if (Collection .class .isAssignableFrom (rawType )) {
337
306
if (SortedSet .class .isAssignableFrom (rawType )) {
338
- return new ObjectConstructor <T >() {
339
- @ Override
340
- public T construct () {
341
- return (T ) new TreeSet <>();
342
- }
343
- };
307
+ return () -> (T ) new TreeSet <>();
344
308
} else if (Set .class .isAssignableFrom (rawType )) {
345
- return new ObjectConstructor <T >() {
346
- @ Override
347
- public T construct () {
348
- return (T ) new LinkedHashSet <>();
349
- }
350
- };
309
+ return () -> (T ) new LinkedHashSet <>();
351
310
} else if (Queue .class .isAssignableFrom (rawType )) {
352
- return new ObjectConstructor <T >() {
353
- @ Override
354
- public T construct () {
355
- return (T ) new ArrayDeque <>();
356
- }
357
- };
311
+ return () -> (T ) new ArrayDeque <>();
358
312
} else {
359
- return new ObjectConstructor <T >() {
360
- @ Override
361
- public T construct () {
362
- return (T ) new ArrayList <>();
363
- }
364
- };
313
+ return () -> (T ) new ArrayList <>();
365
314
}
366
315
}
367
316
368
317
if (Map .class .isAssignableFrom (rawType )) {
369
318
if (ConcurrentNavigableMap .class .isAssignableFrom (rawType )) {
370
- return new ObjectConstructor <T >() {
371
- @ Override
372
- public T construct () {
373
- return (T ) new ConcurrentSkipListMap <>();
374
- }
375
- };
319
+ return () -> (T ) new ConcurrentSkipListMap <>();
376
320
} else if (ConcurrentMap .class .isAssignableFrom (rawType )) {
377
- return new ObjectConstructor <T >() {
378
- @ Override
379
- public T construct () {
380
- return (T ) new ConcurrentHashMap <>();
381
- }
382
- };
321
+ return () -> (T ) new ConcurrentHashMap <>();
383
322
} else if (SortedMap .class .isAssignableFrom (rawType )) {
384
- return new ObjectConstructor <T >() {
385
- @ Override
386
- public T construct () {
387
- return (T ) new TreeMap <>();
388
- }
389
- };
323
+ return () -> (T ) new TreeMap <>();
390
324
} else if (type instanceof ParameterizedType
391
325
&& !String .class .isAssignableFrom (
392
326
TypeToken .get (((ParameterizedType ) type ).getActualTypeArguments ()[0 ]).getRawType ())) {
393
- return new ObjectConstructor <T >() {
394
- @ Override
395
- public T construct () {
396
- return (T ) new LinkedHashMap <>();
397
- }
398
- };
327
+ return () -> (T ) new LinkedHashMap <>();
399
328
} else {
400
- return new ObjectConstructor <T >() {
401
- @ Override
402
- public T construct () {
403
- return (T ) new LinkedTreeMap <>();
404
- }
405
- };
329
+ return () -> (T ) new LinkedTreeMap <>();
406
330
}
407
331
}
408
332
@@ -411,21 +335,18 @@ public T construct() {
411
335
412
336
private <T > ObjectConstructor <T > newUnsafeAllocator (Class <? super T > rawType ) {
413
337
if (useJdkUnsafe ) {
414
- return new ObjectConstructor <T >() {
415
- @ Override
416
- public T construct () {
417
- try {
418
- @ SuppressWarnings ("unchecked" )
419
- T newInstance = (T ) UnsafeAllocator .INSTANCE .newInstance (rawType );
420
- return newInstance ;
421
- } catch (Exception e ) {
422
- throw new RuntimeException (
423
- ("Unable to create instance of "
424
- + rawType
425
- + ". Registering an InstanceCreator or a TypeAdapter for this type, or adding a"
426
- + " no-args constructor may fix this problem." ),
427
- e );
428
- }
338
+ return () -> {
339
+ try {
340
+ @ SuppressWarnings ("unchecked" )
341
+ T newInstance = (T ) UnsafeAllocator .INSTANCE .newInstance (rawType );
342
+ return newInstance ;
343
+ } catch (Exception e ) {
344
+ throw new RuntimeException (
345
+ ("Unable to create instance of "
346
+ + rawType
347
+ + ". Registering an InstanceCreator or a TypeAdapter for this type, or adding a"
348
+ + " no-args constructor may fix this problem." ),
349
+ e );
429
350
}
430
351
};
431
352
} else {
@@ -444,14 +365,11 @@ public T construct() {
444
365
" Or adjust your R8 configuration to keep the no-args constructor of the class." ;
445
366
}
446
367
447
- // Separate effectively final variable to allow usage in the anonymous class below
368
+ // Separate effectively final variable to allow usage in the lambda below
448
369
String exceptionMessageF = exceptionMessage ;
449
370
450
- return new ObjectConstructor <T >() {
451
- @ Override
452
- public T construct () {
453
- throw new JsonIOException (exceptionMessageF );
454
- }
371
+ return () -> {
372
+ throw new JsonIOException (exceptionMessageF );
455
373
};
456
374
}
457
375
}
0 commit comments