1 /* 2 * Copyright (C) 2008 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.google.gson; 18 19 import com.google.gson.internal.ConstructorConstructor; 20 import com.google.gson.internal.Excluder; 21 import com.google.gson.internal.GsonBuildConfig; 22 import com.google.gson.internal.LazilyParsedNumber; 23 import com.google.gson.internal.Primitives; 24 import com.google.gson.internal.Streams; 25 import com.google.gson.internal.bind.ArrayTypeAdapter; 26 import com.google.gson.internal.bind.CollectionTypeAdapterFactory; 27 import com.google.gson.internal.bind.DateTypeAdapter; 28 import com.google.gson.internal.bind.JsonAdapterAnnotationTypeAdapterFactory; 29 import com.google.gson.internal.bind.JsonTreeReader; 30 import com.google.gson.internal.bind.JsonTreeWriter; 31 import com.google.gson.internal.bind.MapTypeAdapterFactory; 32 import com.google.gson.internal.bind.NumberTypeAdapter; 33 import com.google.gson.internal.bind.ObjectTypeAdapter; 34 import com.google.gson.internal.bind.ReflectiveTypeAdapterFactory; 35 import com.google.gson.internal.bind.SerializationDelegatingTypeAdapter; 36 import com.google.gson.internal.bind.TypeAdapters; 37 import com.google.gson.internal.sql.SqlTypesSupport; 38 import com.google.gson.reflect.TypeToken; 39 import com.google.gson.stream.JsonReader; 40 import com.google.gson.stream.JsonToken; 41 import com.google.gson.stream.JsonWriter; 42 import com.google.gson.stream.MalformedJsonException; 43 import java.io.EOFException; 44 import java.io.IOException; 45 import java.io.Reader; 46 import java.io.StringReader; 47 import java.io.StringWriter; 48 import java.io.Writer; 49 import java.lang.reflect.Type; 50 import java.math.BigDecimal; 51 import java.math.BigInteger; 52 import java.text.DateFormat; 53 import java.util.ArrayList; 54 import java.util.Collections; 55 import java.util.HashMap; 56 import java.util.List; 57 import java.util.Map; 58 import java.util.Objects; 59 import java.util.concurrent.ConcurrentHashMap; 60 import java.util.concurrent.ConcurrentMap; 61 import java.util.concurrent.atomic.AtomicLong; 62 import java.util.concurrent.atomic.AtomicLongArray; 63 64 /** 65 * This is the main class for using Gson. Gson is typically used by first constructing a 66 * Gson instance and then invoking {@link #toJson(Object)} or {@link #fromJson(String, Class)} 67 * methods on it. Gson instances are Thread-safe so you can reuse them freely across multiple 68 * threads. 69 * 70 * <p>You can create a Gson instance by invoking {@code new Gson()} if the default configuration 71 * is all you need. You can also use {@link GsonBuilder} to build a Gson instance with various 72 * configuration options such as versioning support, pretty printing, custom 73 * {@link JsonSerializer}s, {@link JsonDeserializer}s, and {@link InstanceCreator}s.</p> 74 * 75 * <p>Here is an example of how Gson is used for a simple Class: 76 * 77 * <pre> 78 * Gson gson = new Gson(); // Or use new GsonBuilder().create(); 79 * MyType target = new MyType(); 80 * String json = gson.toJson(target); // serializes target to JSON 81 * MyType target2 = gson.fromJson(json, MyType.class); // deserializes json into target2 82 * </pre> 83 * 84 * <p>If the type of the object that you are converting is a {@code ParameterizedType} 85 * (i.e. has at least one type argument, for example {@code List<MyType>}) then for 86 * deserialization you must use a {@code fromJson} method with {@link Type} or {@link TypeToken} 87 * parameter to specify the parameterized type. For serialization specifying a {@code Type} 88 * or {@code TypeToken} is optional, otherwise Gson will use the runtime type of the object. 89 * {@link TypeToken} is a class provided by Gson which helps creating parameterized types. 90 * Here is an example showing how this can be done: 91 * <pre> 92 * TypeToken<List<MyType>> listType = new TypeToken<List<MyType>>() {}; 93 * List<MyType> target = new LinkedList<MyType>(); 94 * target.add(new MyType(1, "abc")); 95 * 96 * Gson gson = new Gson(); 97 * // For serialization you normally do not have to specify the type, Gson will use 98 * // the runtime type of the objects, however you can also specify it explicitly 99 * String json = gson.toJson(target, listType.getType()); 100 * 101 * // But for deserialization you have to specify the type 102 * List<MyType> target2 = gson.fromJson(json, listType); 103 * </pre> 104 * 105 * <p>See the <a href="https://github.com/google/gson/blob/master/UserGuide.md">Gson User Guide</a> 106 * for a more complete set of examples.</p> 107 * 108 * <h2>Lenient JSON handling</h2> 109 * For legacy reasons most of the {@code Gson} methods allow JSON data which does not 110 * comply with the JSON specification, regardless of whether {@link GsonBuilder#setLenient()} 111 * is used or not. If this behavior is not desired, the following workarounds can be used: 112 * 113 * <h3>Serialization</h3> 114 * <ol> 115 * <li>Use {@link #getAdapter(Class)} to obtain the adapter for the type to be serialized 116 * <li>When using an existing {@code JsonWriter}, manually apply the writer settings of this 117 * {@code Gson} instance listed by {@link #newJsonWriter(Writer)}.<br> 118 * Otherwise, when not using an existing {@code JsonWriter}, use {@link #newJsonWriter(Writer)} 119 * to construct one. 120 * <li>Call {@link TypeAdapter#write(JsonWriter, Object)} 121 * </ol> 122 * 123 * <h3>Deserialization</h3> 124 * <ol> 125 * <li>Use {@link #getAdapter(Class)} to obtain the adapter for the type to be deserialized 126 * <li>When using an existing {@code JsonReader}, manually apply the reader settings of this 127 * {@code Gson} instance listed by {@link #newJsonReader(Reader)}.<br> 128 * Otherwise, when not using an existing {@code JsonReader}, use {@link #newJsonReader(Reader)} 129 * to construct one. 130 * <li>Call {@link TypeAdapter#read(JsonReader)} 131 * <li>Call {@link JsonReader#peek()} and verify that the result is {@link JsonToken#END_DOCUMENT} 132 * to make sure there is no trailing data 133 * </ol> 134 * 135 * @see TypeToken 136 * 137 * @author Inderjeet Singh 138 * @author Joel Leitch 139 * @author Jesse Wilson 140 */ 141 public final class Gson { 142 static final boolean DEFAULT_JSON_NON_EXECUTABLE = false; 143 static final boolean DEFAULT_LENIENT = false; 144 static final boolean DEFAULT_PRETTY_PRINT = false; 145 static final boolean DEFAULT_ESCAPE_HTML = true; 146 static final boolean DEFAULT_SERIALIZE_NULLS = false; 147 static final boolean DEFAULT_COMPLEX_MAP_KEYS = false; 148 static final boolean DEFAULT_SPECIALIZE_FLOAT_VALUES = false; 149 static final boolean DEFAULT_USE_JDK_UNSAFE = true; 150 static final String DEFAULT_DATE_PATTERN = null; 151 static final FieldNamingStrategy DEFAULT_FIELD_NAMING_STRATEGY = FieldNamingPolicy.IDENTITY; 152 static final ToNumberStrategy DEFAULT_OBJECT_TO_NUMBER_STRATEGY = ToNumberPolicy.DOUBLE; 153 static final ToNumberStrategy DEFAULT_NUMBER_TO_NUMBER_STRATEGY = ToNumberPolicy.LAZILY_PARSED_NUMBER; 154 155 private static final String JSON_NON_EXECUTABLE_PREFIX = ")]}'\n"; 156 157 /** 158 * This thread local guards against reentrant calls to {@link #getAdapter(TypeToken)}. 159 * In certain object graphs, creating an adapter for a type may recursively 160 * require an adapter for the same type! Without intervention, the recursive 161 * lookup would stack overflow. We cheat by returning a proxy type adapter, 162 * {@link FutureTypeAdapter}, which is wired up once the initial adapter has 163 * been created. 164 * 165 * <p>The map stores the type adapters for ongoing {@code getAdapter} calls, 166 * with the type token provided to {@code getAdapter} as key and either 167 * {@code FutureTypeAdapter} or a regular {@code TypeAdapter} as value. 168 */ 169 private final ThreadLocal<Map<TypeToken<?>, TypeAdapter<?>>> threadLocalAdapterResults = new ThreadLocal<>(); 170 171 private final ConcurrentMap<TypeToken<?>, TypeAdapter<?>> typeTokenCache = new ConcurrentHashMap<>(); 172 173 private final ConstructorConstructor constructorConstructor; 174 private final JsonAdapterAnnotationTypeAdapterFactory jsonAdapterFactory; 175 176 final List<TypeAdapterFactory> factories; 177 178 final Excluder excluder; 179 final FieldNamingStrategy fieldNamingStrategy; 180 final Map<Type, InstanceCreator<?>> instanceCreators; 181 final boolean serializeNulls; 182 final boolean complexMapKeySerialization; 183 final boolean generateNonExecutableJson; 184 final boolean htmlSafe; 185 final boolean prettyPrinting; 186 final boolean lenient; 187 final boolean serializeSpecialFloatingPointValues; 188 final boolean useJdkUnsafe; 189 final String datePattern; 190 final int dateStyle; 191 final int timeStyle; 192 final LongSerializationPolicy longSerializationPolicy; 193 final List<TypeAdapterFactory> builderFactories; 194 final List<TypeAdapterFactory> builderHierarchyFactories; 195 final ToNumberStrategy objectToNumberStrategy; 196 final ToNumberStrategy numberToNumberStrategy; 197 final List<ReflectionAccessFilter> reflectionFilters; 198 199 /** 200 * Constructs a Gson object with default configuration. The default configuration has the 201 * following settings: 202 * <ul> 203 * <li>The JSON generated by <code>toJson</code> methods is in compact representation. This 204 * means that all the unneeded white-space is removed. You can change this behavior with 205 * {@link GsonBuilder#setPrettyPrinting()}. </li> 206 * <li>The generated JSON omits all the fields that are null. Note that nulls in arrays are 207 * kept as is since an array is an ordered list. Moreover, if a field is not null, but its 208 * generated JSON is empty, the field is kept. You can configure Gson to serialize null values 209 * by setting {@link GsonBuilder#serializeNulls()}.</li> 210 * <li>Gson provides default serialization and deserialization for Enums, {@link Map}, 211 * {@link java.net.URL}, {@link java.net.URI}, {@link java.util.Locale}, {@link java.util.Date}, 212 * {@link java.math.BigDecimal}, and {@link java.math.BigInteger} classes. If you would prefer 213 * to change the default representation, you can do so by registering a type adapter through 214 * {@link GsonBuilder#registerTypeAdapter(Type, Object)}. </li> 215 * <li>The default Date format is same as {@link java.text.DateFormat#DEFAULT}. This format 216 * ignores the millisecond portion of the date during serialization. You can change 217 * this by invoking {@link GsonBuilder#setDateFormat(int)} or 218 * {@link GsonBuilder#setDateFormat(String)}. </li> 219 * <li>By default, Gson ignores the {@link com.google.gson.annotations.Expose} annotation. 220 * You can enable Gson to serialize/deserialize only those fields marked with this annotation 221 * through {@link GsonBuilder#excludeFieldsWithoutExposeAnnotation()}. </li> 222 * <li>By default, Gson ignores the {@link com.google.gson.annotations.Since} annotation. You 223 * can enable Gson to use this annotation through {@link GsonBuilder#setVersion(double)}.</li> 224 * <li>The default field naming policy for the output JSON is same as in Java. So, a Java class 225 * field <code>versionNumber</code> will be output as <code>"versionNumber"</code> in 226 * JSON. The same rules are applied for mapping incoming JSON to the Java classes. You can 227 * change this policy through {@link GsonBuilder#setFieldNamingPolicy(FieldNamingPolicy)}.</li> 228 * <li>By default, Gson excludes <code>transient</code> or <code>static</code> fields from 229 * consideration for serialization and deserialization. You can change this behavior through 230 * {@link GsonBuilder#excludeFieldsWithModifiers(int...)}.</li> 231 * </ul> 232 */ Gson()233 public Gson() { 234 this(Excluder.DEFAULT, DEFAULT_FIELD_NAMING_STRATEGY, 235 Collections.<Type, InstanceCreator<?>>emptyMap(), DEFAULT_SERIALIZE_NULLS, 236 DEFAULT_COMPLEX_MAP_KEYS, DEFAULT_JSON_NON_EXECUTABLE, DEFAULT_ESCAPE_HTML, 237 DEFAULT_PRETTY_PRINT, DEFAULT_LENIENT, DEFAULT_SPECIALIZE_FLOAT_VALUES, 238 DEFAULT_USE_JDK_UNSAFE, 239 LongSerializationPolicy.DEFAULT, DEFAULT_DATE_PATTERN, DateFormat.DEFAULT, DateFormat.DEFAULT, 240 Collections.<TypeAdapterFactory>emptyList(), Collections.<TypeAdapterFactory>emptyList(), 241 Collections.<TypeAdapterFactory>emptyList(), DEFAULT_OBJECT_TO_NUMBER_STRATEGY, DEFAULT_NUMBER_TO_NUMBER_STRATEGY, 242 Collections.<ReflectionAccessFilter>emptyList()); 243 } 244 Gson(Excluder excluder, FieldNamingStrategy fieldNamingStrategy, Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls, boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe, boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues, boolean useJdkUnsafe, LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle, int timeStyle, List<TypeAdapterFactory> builderFactories, List<TypeAdapterFactory> builderHierarchyFactories, List<TypeAdapterFactory> factoriesToBeAdded, ToNumberStrategy objectToNumberStrategy, ToNumberStrategy numberToNumberStrategy, List<ReflectionAccessFilter> reflectionFilters)245 Gson(Excluder excluder, FieldNamingStrategy fieldNamingStrategy, 246 Map<Type, InstanceCreator<?>> instanceCreators, boolean serializeNulls, 247 boolean complexMapKeySerialization, boolean generateNonExecutableGson, boolean htmlSafe, 248 boolean prettyPrinting, boolean lenient, boolean serializeSpecialFloatingPointValues, 249 boolean useJdkUnsafe, 250 LongSerializationPolicy longSerializationPolicy, String datePattern, int dateStyle, 251 int timeStyle, List<TypeAdapterFactory> builderFactories, 252 List<TypeAdapterFactory> builderHierarchyFactories, 253 List<TypeAdapterFactory> factoriesToBeAdded, 254 ToNumberStrategy objectToNumberStrategy, ToNumberStrategy numberToNumberStrategy, 255 List<ReflectionAccessFilter> reflectionFilters) { 256 this.excluder = excluder; 257 this.fieldNamingStrategy = fieldNamingStrategy; 258 this.instanceCreators = instanceCreators; 259 this.constructorConstructor = new ConstructorConstructor(instanceCreators, useJdkUnsafe, reflectionFilters); 260 this.serializeNulls = serializeNulls; 261 this.complexMapKeySerialization = complexMapKeySerialization; 262 this.generateNonExecutableJson = generateNonExecutableGson; 263 this.htmlSafe = htmlSafe; 264 this.prettyPrinting = prettyPrinting; 265 this.lenient = lenient; 266 this.serializeSpecialFloatingPointValues = serializeSpecialFloatingPointValues; 267 this.useJdkUnsafe = useJdkUnsafe; 268 this.longSerializationPolicy = longSerializationPolicy; 269 this.datePattern = datePattern; 270 this.dateStyle = dateStyle; 271 this.timeStyle = timeStyle; 272 this.builderFactories = builderFactories; 273 this.builderHierarchyFactories = builderHierarchyFactories; 274 this.objectToNumberStrategy = objectToNumberStrategy; 275 this.numberToNumberStrategy = numberToNumberStrategy; 276 this.reflectionFilters = reflectionFilters; 277 278 List<TypeAdapterFactory> factories = new ArrayList<>(); 279 280 // built-in type adapters that cannot be overridden 281 factories.add(TypeAdapters.JSON_ELEMENT_FACTORY); 282 factories.add(ObjectTypeAdapter.getFactory(objectToNumberStrategy)); 283 284 // the excluder must precede all adapters that handle user-defined types 285 factories.add(excluder); 286 287 // users' type adapters 288 factories.addAll(factoriesToBeAdded); 289 290 // type adapters for basic platform types 291 factories.add(TypeAdapters.STRING_FACTORY); 292 factories.add(TypeAdapters.INTEGER_FACTORY); 293 factories.add(TypeAdapters.BOOLEAN_FACTORY); 294 factories.add(TypeAdapters.BYTE_FACTORY); 295 factories.add(TypeAdapters.SHORT_FACTORY); 296 TypeAdapter<Number> longAdapter = longAdapter(longSerializationPolicy); 297 factories.add(TypeAdapters.newFactory(long.class, Long.class, longAdapter)); 298 factories.add(TypeAdapters.newFactory(double.class, Double.class, 299 doubleAdapter(serializeSpecialFloatingPointValues))); 300 factories.add(TypeAdapters.newFactory(float.class, Float.class, 301 floatAdapter(serializeSpecialFloatingPointValues))); 302 factories.add(NumberTypeAdapter.getFactory(numberToNumberStrategy)); 303 factories.add(TypeAdapters.ATOMIC_INTEGER_FACTORY); 304 factories.add(TypeAdapters.ATOMIC_BOOLEAN_FACTORY); 305 factories.add(TypeAdapters.newFactory(AtomicLong.class, atomicLongAdapter(longAdapter))); 306 factories.add(TypeAdapters.newFactory(AtomicLongArray.class, atomicLongArrayAdapter(longAdapter))); 307 factories.add(TypeAdapters.ATOMIC_INTEGER_ARRAY_FACTORY); 308 factories.add(TypeAdapters.CHARACTER_FACTORY); 309 factories.add(TypeAdapters.STRING_BUILDER_FACTORY); 310 factories.add(TypeAdapters.STRING_BUFFER_FACTORY); 311 factories.add(TypeAdapters.newFactory(BigDecimal.class, TypeAdapters.BIG_DECIMAL)); 312 factories.add(TypeAdapters.newFactory(BigInteger.class, TypeAdapters.BIG_INTEGER)); 313 // Add adapter for LazilyParsedNumber because user can obtain it from Gson and then try to serialize it again 314 factories.add(TypeAdapters.newFactory(LazilyParsedNumber.class, TypeAdapters.LAZILY_PARSED_NUMBER)); 315 factories.add(TypeAdapters.URL_FACTORY); 316 factories.add(TypeAdapters.URI_FACTORY); 317 factories.add(TypeAdapters.UUID_FACTORY); 318 factories.add(TypeAdapters.CURRENCY_FACTORY); 319 factories.add(TypeAdapters.LOCALE_FACTORY); 320 factories.add(TypeAdapters.INET_ADDRESS_FACTORY); 321 factories.add(TypeAdapters.BIT_SET_FACTORY); 322 factories.add(DateTypeAdapter.FACTORY); 323 factories.add(TypeAdapters.CALENDAR_FACTORY); 324 325 if (SqlTypesSupport.SUPPORTS_SQL_TYPES) { 326 factories.add(SqlTypesSupport.TIME_FACTORY); 327 factories.add(SqlTypesSupport.DATE_FACTORY); 328 factories.add(SqlTypesSupport.TIMESTAMP_FACTORY); 329 } 330 331 factories.add(ArrayTypeAdapter.FACTORY); 332 factories.add(TypeAdapters.CLASS_FACTORY); 333 334 // type adapters for composite and user-defined types 335 factories.add(new CollectionTypeAdapterFactory(constructorConstructor)); 336 factories.add(new MapTypeAdapterFactory(constructorConstructor, complexMapKeySerialization)); 337 this.jsonAdapterFactory = new JsonAdapterAnnotationTypeAdapterFactory(constructorConstructor); 338 factories.add(jsonAdapterFactory); 339 factories.add(TypeAdapters.ENUM_FACTORY); 340 factories.add(new ReflectiveTypeAdapterFactory( 341 constructorConstructor, fieldNamingStrategy, excluder, jsonAdapterFactory, reflectionFilters)); 342 343 this.factories = Collections.unmodifiableList(factories); 344 } 345 346 /** 347 * Returns a new GsonBuilder containing all custom factories and configuration used by the current 348 * instance. 349 * 350 * @return a GsonBuilder instance. 351 * @since 2.8.3 352 */ newBuilder()353 public GsonBuilder newBuilder() { 354 return new GsonBuilder(this); 355 } 356 357 /** 358 * @deprecated This method by accident exposes an internal Gson class; it might be removed in a 359 * future version. 360 */ 361 @Deprecated excluder()362 public Excluder excluder() { 363 return excluder; 364 } 365 366 /** 367 * Returns the field naming strategy used by this Gson instance. 368 * 369 * @see GsonBuilder#setFieldNamingStrategy(FieldNamingStrategy) 370 */ fieldNamingStrategy()371 public FieldNamingStrategy fieldNamingStrategy() { 372 return fieldNamingStrategy; 373 } 374 375 /** 376 * Returns whether this Gson instance is serializing JSON object properties with 377 * {@code null} values, or just omits them. 378 * 379 * @see GsonBuilder#serializeNulls() 380 */ serializeNulls()381 public boolean serializeNulls() { 382 return serializeNulls; 383 } 384 385 /** 386 * Returns whether this Gson instance produces JSON output which is 387 * HTML-safe, that means all HTML characters are escaped. 388 * 389 * @see GsonBuilder#disableHtmlEscaping() 390 */ htmlSafe()391 public boolean htmlSafe() { 392 return htmlSafe; 393 } 394 doubleAdapter(boolean serializeSpecialFloatingPointValues)395 private TypeAdapter<Number> doubleAdapter(boolean serializeSpecialFloatingPointValues) { 396 if (serializeSpecialFloatingPointValues) { 397 return TypeAdapters.DOUBLE; 398 } 399 return new TypeAdapter<Number>() { 400 @Override public Double read(JsonReader in) throws IOException { 401 if (in.peek() == JsonToken.NULL) { 402 in.nextNull(); 403 return null; 404 } 405 return in.nextDouble(); 406 } 407 @Override public void write(JsonWriter out, Number value) throws IOException { 408 if (value == null) { 409 out.nullValue(); 410 return; 411 } 412 double doubleValue = value.doubleValue(); 413 checkValidFloatingPoint(doubleValue); 414 out.value(doubleValue); 415 } 416 }; 417 } 418 419 private TypeAdapter<Number> floatAdapter(boolean serializeSpecialFloatingPointValues) { 420 if (serializeSpecialFloatingPointValues) { 421 return TypeAdapters.FLOAT; 422 } 423 return new TypeAdapter<Number>() { 424 @Override public Float read(JsonReader in) throws IOException { 425 if (in.peek() == JsonToken.NULL) { 426 in.nextNull(); 427 return null; 428 } 429 return (float) in.nextDouble(); 430 } 431 @Override public void write(JsonWriter out, Number value) throws IOException { 432 if (value == null) { 433 out.nullValue(); 434 return; 435 } 436 float floatValue = value.floatValue(); 437 checkValidFloatingPoint(floatValue); 438 // For backward compatibility don't call `JsonWriter.value(float)` because that method has 439 // been newly added and not all custom JsonWriter implementations might override it yet 440 Number floatNumber = value instanceof Float ? value : floatValue; 441 out.value(floatNumber); 442 } 443 }; 444 } 445 446 static void checkValidFloatingPoint(double value) { 447 if (Double.isNaN(value) || Double.isInfinite(value)) { 448 throw new IllegalArgumentException(value 449 + " is not a valid double value as per JSON specification. To override this" 450 + " behavior, use GsonBuilder.serializeSpecialFloatingPointValues() method."); 451 } 452 } 453 454 private static TypeAdapter<Number> longAdapter(LongSerializationPolicy longSerializationPolicy) { 455 if (longSerializationPolicy == LongSerializationPolicy.DEFAULT) { 456 return TypeAdapters.LONG; 457 } 458 return new TypeAdapter<Number>() { 459 @Override public Number read(JsonReader in) throws IOException { 460 if (in.peek() == JsonToken.NULL) { 461 in.nextNull(); 462 return null; 463 } 464 return in.nextLong(); 465 } 466 @Override public void write(JsonWriter out, Number value) throws IOException { 467 if (value == null) { 468 out.nullValue(); 469 return; 470 } 471 out.value(value.toString()); 472 } 473 }; 474 } 475 476 private static TypeAdapter<AtomicLong> atomicLongAdapter(final TypeAdapter<Number> longAdapter) { 477 return new TypeAdapter<AtomicLong>() { 478 @Override public void write(JsonWriter out, AtomicLong value) throws IOException { 479 longAdapter.write(out, value.get()); 480 } 481 @Override public AtomicLong read(JsonReader in) throws IOException { 482 Number value = longAdapter.read(in); 483 return new AtomicLong(value.longValue()); 484 } 485 }.nullSafe(); 486 } 487 488 private static TypeAdapter<AtomicLongArray> atomicLongArrayAdapter(final TypeAdapter<Number> longAdapter) { 489 return new TypeAdapter<AtomicLongArray>() { 490 @Override public void write(JsonWriter out, AtomicLongArray value) throws IOException { 491 out.beginArray(); 492 for (int i = 0, length = value.length(); i < length; i++) { 493 longAdapter.write(out, value.get(i)); 494 } 495 out.endArray(); 496 } 497 @Override public AtomicLongArray read(JsonReader in) throws IOException { 498 List<Long> list = new ArrayList<>(); 499 in.beginArray(); 500 while (in.hasNext()) { 501 long value = longAdapter.read(in).longValue(); 502 list.add(value); 503 } 504 in.endArray(); 505 int length = list.size(); 506 AtomicLongArray array = new AtomicLongArray(length); 507 for (int i = 0; i < length; ++i) { 508 array.set(i, list.get(i)); 509 } 510 return array; 511 } 512 }.nullSafe(); 513 } 514 515 /** 516 * Returns the type adapter for {@code type}. 517 * 518 * <p>When calling this method concurrently from multiple threads and requesting 519 * an adapter for the same type this method may return different {@code TypeAdapter} 520 * instances. However, that should normally not be an issue because {@code TypeAdapter} 521 * implementations are supposed to be stateless. 522 * 523 * @throws IllegalArgumentException if this Gson instance cannot serialize and 524 * deserialize {@code type}. 525 */ 526 public <T> TypeAdapter<T> getAdapter(TypeToken<T> type) { 527 Objects.requireNonNull(type, "type must not be null"); 528 TypeAdapter<?> cached = typeTokenCache.get(type); 529 if (cached != null) { 530 @SuppressWarnings("unchecked") 531 TypeAdapter<T> adapter = (TypeAdapter<T>) cached; 532 return adapter; 533 } 534 535 Map<TypeToken<?>, TypeAdapter<?>> threadCalls = threadLocalAdapterResults.get(); 536 boolean isInitialAdapterRequest = false; 537 if (threadCalls == null) { 538 threadCalls = new HashMap<>(); 539 threadLocalAdapterResults.set(threadCalls); 540 isInitialAdapterRequest = true; 541 } else { 542 // the key and value type parameters always agree 543 @SuppressWarnings("unchecked") 544 TypeAdapter<T> ongoingCall = (TypeAdapter<T>) threadCalls.get(type); 545 if (ongoingCall != null) { 546 return ongoingCall; 547 } 548 } 549 550 TypeAdapter<T> candidate = null; 551 try { 552 FutureTypeAdapter<T> call = new FutureTypeAdapter<>(); 553 threadCalls.put(type, call); 554 555 for (TypeAdapterFactory factory : factories) { 556 candidate = factory.create(this, type); 557 if (candidate != null) { 558 call.setDelegate(candidate); 559 // Replace future adapter with actual adapter 560 threadCalls.put(type, candidate); 561 break; 562 } 563 } 564 } finally { 565 if (isInitialAdapterRequest) { 566 threadLocalAdapterResults.remove(); 567 } 568 } 569 570 if (candidate == null) { 571 throw new IllegalArgumentException("GSON (" + GsonBuildConfig.VERSION + ") cannot handle " + type); 572 } 573 574 if (isInitialAdapterRequest) { 575 /* 576 * Publish resolved adapters to all threads 577 * Can only do this for the initial request because cyclic dependency TypeA -> TypeB -> TypeA 578 * would otherwise publish adapter for TypeB which uses not yet resolved adapter for TypeA 579 * See https://github.com/google/gson/issues/625 580 */ 581 typeTokenCache.putAll(threadCalls); 582 } 583 return candidate; 584 } 585 586 /** 587 * This method is used to get an alternate type adapter for the specified type. This is used 588 * to access a type adapter that is overridden by a {@link TypeAdapterFactory} that you 589 * may have registered. This features is typically used when you want to register a type 590 * adapter that does a little bit of work but then delegates further processing to the Gson 591 * default type adapter. Here is an example: 592 * <p>Let's say we want to write a type adapter that counts the number of objects being read 593 * from or written to JSON. We can achieve this by writing a type adapter factory that uses 594 * the <code>getDelegateAdapter</code> method: 595 * <pre> {@code 596 * class StatsTypeAdapterFactory implements TypeAdapterFactory { 597 * public int numReads = 0; 598 * public int numWrites = 0; 599 * public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { 600 * final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type); 601 * return new TypeAdapter<T>() { 602 * public void write(JsonWriter out, T value) throws IOException { 603 * ++numWrites; 604 * delegate.write(out, value); 605 * } 606 * public T read(JsonReader in) throws IOException { 607 * ++numReads; 608 * return delegate.read(in); 609 * } 610 * }; 611 * } 612 * } 613 * } </pre> 614 * This factory can now be used like this: 615 * <pre> {@code 616 * StatsTypeAdapterFactory stats = new StatsTypeAdapterFactory(); 617 * Gson gson = new GsonBuilder().registerTypeAdapterFactory(stats).create(); 618 * // Call gson.toJson() and fromJson methods on objects 619 * System.out.println("Num JSON reads" + stats.numReads); 620 * System.out.println("Num JSON writes" + stats.numWrites); 621 * }</pre> 622 * Note that this call will skip all factories registered before {@code skipPast}. In case of 623 * multiple TypeAdapterFactories registered it is up to the caller of this function to insure 624 * that the order of registration does not prevent this method from reaching a factory they 625 * would expect to reply from this call. 626 * Note that since you can not override type adapter factories for String and Java primitive 627 * types, our stats factory will not count the number of String or primitives that will be 628 * read or written. 629 * @param skipPast The type adapter factory that needs to be skipped while searching for 630 * a matching type adapter. In most cases, you should just pass <i>this</i> (the type adapter 631 * factory from where {@code getDelegateAdapter} method is being invoked). 632 * @param type Type for which the delegate adapter is being searched for. 633 * 634 * @since 2.2 635 */ 636 public <T> TypeAdapter<T> getDelegateAdapter(TypeAdapterFactory skipPast, TypeToken<T> type) { 637 // Hack. If the skipPast factory isn't registered, assume the factory is being requested via 638 // our @JsonAdapter annotation. 639 if (!factories.contains(skipPast)) { 640 skipPast = jsonAdapterFactory; 641 } 642 643 boolean skipPastFound = false; 644 for (TypeAdapterFactory factory : factories) { 645 if (!skipPastFound) { 646 if (factory == skipPast) { 647 skipPastFound = true; 648 } 649 continue; 650 } 651 652 TypeAdapter<T> candidate = factory.create(this, type); 653 if (candidate != null) { 654 return candidate; 655 } 656 } 657 throw new IllegalArgumentException("GSON cannot serialize " + type); 658 } 659 660 /** 661 * Returns the type adapter for {@code type}. 662 * 663 * @throws IllegalArgumentException if this Gson instance cannot serialize and 664 * deserialize {@code type}. 665 */ 666 public <T> TypeAdapter<T> getAdapter(Class<T> type) { 667 return getAdapter(TypeToken.get(type)); 668 } 669 670 /** 671 * This method serializes the specified object into its equivalent representation as a tree of 672 * {@link JsonElement}s. This method should be used when the specified object is not a generic 673 * type. This method uses {@link Class#getClass()} to get the type for the specified object, but 674 * the {@code getClass()} loses the generic type information because of the Type Erasure feature 675 * of Java. Note that this method works fine if any of the object fields are of generic type, 676 * just the object itself should not be of a generic type. If the object is of generic type, use 677 * {@link #toJsonTree(Object, Type)} instead. 678 * 679 * @param src the object for which JSON representation is to be created 680 * @return JSON representation of {@code src}. 681 * @since 1.4 682 * 683 * @see #toJsonTree(Object, Type) 684 */ 685 public JsonElement toJsonTree(Object src) { 686 if (src == null) { 687 return JsonNull.INSTANCE; 688 } 689 return toJsonTree(src, src.getClass()); 690 } 691 692 /** 693 * This method serializes the specified object, including those of generic types, into its 694 * equivalent representation as a tree of {@link JsonElement}s. This method must be used if the 695 * specified object is a generic type. For non-generic objects, use {@link #toJsonTree(Object)} 696 * instead. 697 * 698 * @param src the object for which JSON representation is to be created 699 * @param typeOfSrc The specific genericized type of src. You can obtain 700 * this type by using the {@link com.google.gson.reflect.TypeToken} class. For example, 701 * to get the type for {@code Collection<Foo>}, you should use: 702 * <pre> 703 * Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType(); 704 * </pre> 705 * @return Json representation of {@code src} 706 * @since 1.4 707 * 708 * @see #toJsonTree(Object) 709 */ 710 public JsonElement toJsonTree(Object src, Type typeOfSrc) { 711 JsonTreeWriter writer = new JsonTreeWriter(); 712 toJson(src, typeOfSrc, writer); 713 return writer.get(); 714 } 715 716 /** 717 * This method serializes the specified object into its equivalent JSON representation. 718 * This method should be used when the specified object is not a generic type. This method uses 719 * {@link Class#getClass()} to get the type for the specified object, but the 720 * {@code getClass()} loses the generic type information because of the Type Erasure feature 721 * of Java. Note that this method works fine if any of the object fields are of generic type, 722 * just the object itself should not be of a generic type. If the object is of generic type, use 723 * {@link #toJson(Object, Type)} instead. If you want to write out the object to a 724 * {@link Writer}, use {@link #toJson(Object, Appendable)} instead. 725 * 726 * @param src the object for which JSON representation is to be created 727 * @return Json representation of {@code src}. 728 * 729 * @see #toJson(Object, Appendable) 730 * @see #toJson(Object, Type) 731 */ 732 public String toJson(Object src) { 733 if (src == null) { 734 return toJson(JsonNull.INSTANCE); 735 } 736 return toJson(src, src.getClass()); 737 } 738 739 /** 740 * This method serializes the specified object, including those of generic types, into its 741 * equivalent JSON representation. This method must be used if the specified object is a generic 742 * type. For non-generic objects, use {@link #toJson(Object)} instead. If you want to write out 743 * the object to a {@link Appendable}, use {@link #toJson(Object, Type, Appendable)} instead. 744 * 745 * @param src the object for which JSON representation is to be created 746 * @param typeOfSrc The specific genericized type of src. You can obtain 747 * this type by using the {@link com.google.gson.reflect.TypeToken} class. For example, 748 * to get the type for {@code Collection<Foo>}, you should use: 749 * <pre> 750 * Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType(); 751 * </pre> 752 * @return JSON representation of {@code src} 753 * 754 * @see #toJson(Object, Type, Appendable) 755 * @see #toJson(Object) 756 */ 757 public String toJson(Object src, Type typeOfSrc) { 758 StringWriter writer = new StringWriter(); 759 toJson(src, typeOfSrc, writer); 760 return writer.toString(); 761 } 762 763 /** 764 * This method serializes the specified object into its equivalent JSON representation and 765 * writes it to the writer. 766 * This method should be used when the specified object is not a generic type. This method uses 767 * {@link Class#getClass()} to get the type for the specified object, but the 768 * {@code getClass()} loses the generic type information because of the Type Erasure feature 769 * of Java. Note that this method works fine if any of the object fields are of generic type, 770 * just the object itself should not be of a generic type. If the object is of generic type, use 771 * {@link #toJson(Object, Type, Appendable)} instead. 772 * 773 * @param src the object for which JSON representation is to be created 774 * @param writer Writer to which the JSON representation needs to be written 775 * @throws JsonIOException if there was a problem writing to the writer 776 * @since 1.2 777 * 778 * @see #toJson(Object) 779 * @see #toJson(Object, Type, Appendable) 780 */ 781 public void toJson(Object src, Appendable writer) throws JsonIOException { 782 if (src != null) { 783 toJson(src, src.getClass(), writer); 784 } else { 785 toJson(JsonNull.INSTANCE, writer); 786 } 787 } 788 789 /** 790 * This method serializes the specified object, including those of generic types, into its 791 * equivalent JSON representation and writes it to the writer. 792 * This method must be used if the specified object is a generic type. For non-generic objects, 793 * use {@link #toJson(Object, Appendable)} instead. 794 * 795 * @param src the object for which JSON representation is to be created 796 * @param typeOfSrc The specific genericized type of src. You can obtain 797 * this type by using the {@link com.google.gson.reflect.TypeToken} class. For example, 798 * to get the type for {@code Collection<Foo>}, you should use: 799 * <pre> 800 * Type typeOfSrc = new TypeToken<Collection<Foo>>(){}.getType(); 801 * </pre> 802 * @param writer Writer to which the JSON representation of src needs to be written. 803 * @throws JsonIOException if there was a problem writing to the writer 804 * @since 1.2 805 * 806 * @see #toJson(Object, Type) 807 * @see #toJson(Object, Appendable) 808 */ 809 public void toJson(Object src, Type typeOfSrc, Appendable writer) throws JsonIOException { 810 try { 811 JsonWriter jsonWriter = newJsonWriter(Streams.writerForAppendable(writer)); 812 toJson(src, typeOfSrc, jsonWriter); 813 } catch (IOException e) { 814 throw new JsonIOException(e); 815 } 816 } 817 818 /** 819 * Writes the JSON representation of {@code src} of type {@code typeOfSrc} to 820 * {@code writer}. 821 * 822 * <p>The JSON data is written in {@linkplain JsonWriter#setLenient(boolean) lenient mode}, 823 * regardless of the lenient mode setting of the provided writer. The lenient mode setting 824 * of the writer is restored once this method returns. 825 * 826 * <p>The 'HTML-safe' and 'serialize {@code null}' settings of this {@code Gson} instance 827 * (configured by the {@link GsonBuilder}) are applied, and the original settings of the 828 * writer are restored once this method returns. 829 * 830 * @throws JsonIOException if there was a problem writing to the writer 831 */ 832 public void toJson(Object src, Type typeOfSrc, JsonWriter writer) throws JsonIOException { 833 @SuppressWarnings("unchecked") 834 TypeAdapter<Object> adapter = (TypeAdapter<Object>) getAdapter(TypeToken.get(typeOfSrc)); 835 boolean oldLenient = writer.isLenient(); 836 writer.setLenient(true); 837 boolean oldHtmlSafe = writer.isHtmlSafe(); 838 writer.setHtmlSafe(htmlSafe); 839 boolean oldSerializeNulls = writer.getSerializeNulls(); 840 writer.setSerializeNulls(serializeNulls); 841 try { 842 adapter.write(writer, src); 843 } catch (IOException e) { 844 throw new JsonIOException(e); 845 } catch (AssertionError e) { 846 throw new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage(), e); 847 } finally { 848 writer.setLenient(oldLenient); 849 writer.setHtmlSafe(oldHtmlSafe); 850 writer.setSerializeNulls(oldSerializeNulls); 851 } 852 } 853 854 /** 855 * Converts a tree of {@link JsonElement}s into its equivalent JSON representation. 856 * 857 * @param jsonElement root of a tree of {@link JsonElement}s 858 * @return JSON String representation of the tree 859 * @since 1.4 860 */ 861 public String toJson(JsonElement jsonElement) { 862 StringWriter writer = new StringWriter(); 863 toJson(jsonElement, writer); 864 return writer.toString(); 865 } 866 867 /** 868 * Writes out the equivalent JSON for a tree of {@link JsonElement}s. 869 * 870 * @param jsonElement root of a tree of {@link JsonElement}s 871 * @param writer Writer to which the JSON representation needs to be written 872 * @throws JsonIOException if there was a problem writing to the writer 873 * @since 1.4 874 */ 875 public void toJson(JsonElement jsonElement, Appendable writer) throws JsonIOException { 876 try { 877 JsonWriter jsonWriter = newJsonWriter(Streams.writerForAppendable(writer)); 878 toJson(jsonElement, jsonWriter); 879 } catch (IOException e) { 880 throw new JsonIOException(e); 881 } 882 } 883 884 /** 885 * Returns a new JSON writer configured for the settings on this Gson instance. 886 * 887 * <p>The following settings are considered: 888 * <ul> 889 * <li>{@link GsonBuilder#disableHtmlEscaping()}</li> 890 * <li>{@link GsonBuilder#generateNonExecutableJson()}</li> 891 * <li>{@link GsonBuilder#serializeNulls()}</li> 892 * <li>{@link GsonBuilder#setLenient()}</li> 893 * <li>{@link GsonBuilder#setPrettyPrinting()}</li> 894 * </ul> 895 */ 896 public JsonWriter newJsonWriter(Writer writer) throws IOException { 897 if (generateNonExecutableJson) { 898 writer.write(JSON_NON_EXECUTABLE_PREFIX); 899 } 900 JsonWriter jsonWriter = new JsonWriter(writer); 901 if (prettyPrinting) { 902 jsonWriter.setIndent(" "); 903 } 904 jsonWriter.setHtmlSafe(htmlSafe); 905 jsonWriter.setLenient(lenient); 906 jsonWriter.setSerializeNulls(serializeNulls); 907 return jsonWriter; 908 } 909 910 /** 911 * Returns a new JSON reader configured for the settings on this Gson instance. 912 * 913 * <p>The following settings are considered: 914 * <ul> 915 * <li>{@link GsonBuilder#setLenient()}</li> 916 * </ul> 917 */ 918 public JsonReader newJsonReader(Reader reader) { 919 JsonReader jsonReader = new JsonReader(reader); 920 jsonReader.setLenient(lenient); 921 return jsonReader; 922 } 923 924 /** 925 * Writes the JSON for {@code jsonElement} to {@code writer}. 926 * 927 * <p>The JSON data is written in {@linkplain JsonWriter#setLenient(boolean) lenient mode}, 928 * regardless of the lenient mode setting of the provided writer. The lenient mode setting 929 * of the writer is restored once this method returns. 930 * 931 * <p>The 'HTML-safe' and 'serialize {@code null}' settings of this {@code Gson} instance 932 * (configured by the {@link GsonBuilder}) are applied, and the original settings of the 933 * writer are restored once this method returns. 934 * 935 * @throws JsonIOException if there was a problem writing to the writer 936 */ 937 public void toJson(JsonElement jsonElement, JsonWriter writer) throws JsonIOException { 938 boolean oldLenient = writer.isLenient(); 939 writer.setLenient(true); 940 boolean oldHtmlSafe = writer.isHtmlSafe(); 941 writer.setHtmlSafe(htmlSafe); 942 boolean oldSerializeNulls = writer.getSerializeNulls(); 943 writer.setSerializeNulls(serializeNulls); 944 try { 945 Streams.write(jsonElement, writer); 946 } catch (IOException e) { 947 throw new JsonIOException(e); 948 } catch (AssertionError e) { 949 throw new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage(), e); 950 } finally { 951 writer.setLenient(oldLenient); 952 writer.setHtmlSafe(oldHtmlSafe); 953 writer.setSerializeNulls(oldSerializeNulls); 954 } 955 } 956 957 /** 958 * This method deserializes the specified JSON into an object of the specified class. It is not 959 * suitable to use if the specified class is a generic type since it will not have the generic 960 * type information because of the Type Erasure feature of Java. Therefore, this method should not 961 * be used if the desired type is a generic type. Note that this method works fine if the any of 962 * the fields of the specified object are generics, just the object itself should not be a 963 * generic type. For the cases when the object is of generic type, invoke 964 * {@link #fromJson(String, TypeToken)}. If you have the JSON in a {@link Reader} instead of 965 * a String, use {@link #fromJson(Reader, Class)} instead. 966 * 967 * <p>An exception is thrown if the JSON string has multiple top-level JSON elements, or if there 968 * is trailing data. Use {@link #fromJson(JsonReader, Type)} if this behavior is not desired. 969 * 970 * @param <T> the type of the desired object 971 * @param json the string from which the object is to be deserialized 972 * @param classOfT the class of T 973 * @return an object of type T from the string. Returns {@code null} if {@code json} is {@code null} 974 * or if {@code json} is empty. 975 * @throws JsonSyntaxException if json is not a valid representation for an object of type 976 * classOfT 977 * 978 * @see #fromJson(Reader, Class) 979 * @see #fromJson(String, TypeToken) 980 */ 981 public <T> T fromJson(String json, Class<T> classOfT) throws JsonSyntaxException { 982 T object = fromJson(json, TypeToken.get(classOfT)); 983 return Primitives.wrap(classOfT).cast(object); 984 } 985 986 /** 987 * This method deserializes the specified JSON into an object of the specified type. This method 988 * is useful if the specified object is a generic type. For non-generic objects, use 989 * {@link #fromJson(String, Class)} instead. If you have the JSON in a {@link Reader} instead of 990 * a String, use {@link #fromJson(Reader, Type)} instead. 991 * 992 * <p>Since {@code Type} is not parameterized by T, this method is not type-safe and 993 * should be used carefully. If you are creating the {@code Type} from a {@link TypeToken}, 994 * prefer using {@link #fromJson(String, TypeToken)} instead since its return type is based 995 * on the {@code TypeToken} and is therefore more type-safe. 996 * 997 * <p>An exception is thrown if the JSON string has multiple top-level JSON elements, 998 * or if there is trailing data. Use {@link #fromJson(JsonReader, Type)} if this behavior is 999 * not desired. 1000 * 1001 * @param <T> the type of the desired object 1002 * @param json the string from which the object is to be deserialized 1003 * @param typeOfT The specific genericized type of src 1004 * @return an object of type T from the string. Returns {@code null} if {@code json} is {@code null} 1005 * or if {@code json} is empty. 1006 * @throws JsonSyntaxException if json is not a valid representation for an object of type typeOfT 1007 * 1008 * @see #fromJson(Reader, Type) 1009 * @see #fromJson(String, Class) 1010 * @see #fromJson(String, TypeToken) 1011 */ 1012 @SuppressWarnings("unchecked") 1013 public <T> T fromJson(String json, Type typeOfT) throws JsonSyntaxException { 1014 return (T) fromJson(json, TypeToken.get(typeOfT)); 1015 } 1016 1017 /** 1018 * This method deserializes the specified JSON into an object of the specified type. This method 1019 * is useful if the specified object is a generic type. For non-generic objects, use 1020 * {@link #fromJson(String, Class)} instead. If you have the JSON in a {@link Reader} instead of 1021 * a String, use {@link #fromJson(Reader, TypeToken)} instead. 1022 * 1023 * <p>An exception is thrown if the JSON string has multiple top-level JSON elements, or if there 1024 * is trailing data. Use {@link #fromJson(JsonReader, TypeToken)} if this behavior is not desired. 1025 * 1026 * @param <T> the type of the desired object 1027 * @param json the string from which the object is to be deserialized 1028 * @param typeOfT The specific genericized type of src. You should create an anonymous subclass of 1029 * {@code TypeToken} with the specific generic type arguments. For example, to get the type for 1030 * {@code Collection<Foo>}, you should use: 1031 * <pre> 1032 * new TypeToken<Collection<Foo>>(){} 1033 * </pre> 1034 * @return an object of type T from the string. Returns {@code null} if {@code json} is {@code null} 1035 * or if {@code json} is empty. 1036 * @throws JsonSyntaxException if json is not a valid representation for an object of the type typeOfT 1037 * 1038 * @see #fromJson(Reader, TypeToken) 1039 * @see #fromJson(String, Class) 1040 * @since 2.10 1041 */ 1042 public <T> T fromJson(String json, TypeToken<T> typeOfT) throws JsonSyntaxException { 1043 if (json == null) { 1044 return null; 1045 } 1046 StringReader reader = new StringReader(json); 1047 return fromJson(reader, typeOfT); 1048 } 1049 1050 /** 1051 * This method deserializes the JSON read from the specified reader into an object of the 1052 * specified class. It is not suitable to use if the specified class is a generic type since it 1053 * will not have the generic type information because of the Type Erasure feature of Java. 1054 * Therefore, this method should not be used if the desired type is a generic type. Note that 1055 * this method works fine if any of the fields of the specified object are generics, just the 1056 * object itself should not be a generic type. For the cases when the object is of generic type, 1057 * invoke {@link #fromJson(Reader, TypeToken)}. If you have the JSON in a String form instead of a 1058 * {@link Reader}, use {@link #fromJson(String, Class)} instead. 1059 * 1060 * <p>An exception is thrown if the JSON data has multiple top-level JSON elements, or if there 1061 * is trailing data. Use {@link #fromJson(JsonReader, Type)} if this behavior is not desired. 1062 * 1063 * @param <T> the type of the desired object 1064 * @param json the reader producing the JSON from which the object is to be deserialized. 1065 * @param classOfT the class of T 1066 * @return an object of type T from the Reader. Returns {@code null} if {@code json} is at EOF. 1067 * @throws JsonIOException if there was a problem reading from the Reader 1068 * @throws JsonSyntaxException if json is not a valid representation for an object of type typeOfT 1069 * @since 1.2 1070 * 1071 * @see #fromJson(String, Class) 1072 * @see #fromJson(Reader, TypeToken) 1073 */ 1074 public <T> T fromJson(Reader json, Class<T> classOfT) throws JsonSyntaxException, JsonIOException { 1075 T object = fromJson(json, TypeToken.get(classOfT)); 1076 return Primitives.wrap(classOfT).cast(object); 1077 } 1078 1079 /** 1080 * This method deserializes the JSON read from the specified reader into an object of the 1081 * specified type. This method is useful if the specified object is a generic type. For 1082 * non-generic objects, use {@link #fromJson(Reader, Class)} instead. If you have the JSON in a 1083 * String form instead of a {@link Reader}, use {@link #fromJson(String, Type)} instead. 1084 * 1085 * <p>Since {@code Type} is not parameterized by T, this method is not type-safe and 1086 * should be used carefully. If you are creating the {@code Type} from a {@link TypeToken}, 1087 * prefer using {@link #fromJson(Reader, TypeToken)} instead since its return type is based 1088 * on the {@code TypeToken} and is therefore more type-safe. 1089 * 1090 * <p>An exception is thrown if the JSON data has multiple top-level JSON elements, or if there 1091 * is trailing data. Use {@link #fromJson(JsonReader, Type)} if this behavior is not desired. 1092 * 1093 * @param <T> the type of the desired object 1094 * @param json the reader producing JSON from which the object is to be deserialized 1095 * @param typeOfT The specific genericized type of src 1096 * @return an object of type T from the Reader. Returns {@code null} if {@code json} is at EOF. 1097 * @throws JsonIOException if there was a problem reading from the Reader 1098 * @throws JsonSyntaxException if json is not a valid representation for an object of type typeOfT 1099 * @since 1.2 1100 * 1101 * @see #fromJson(String, Type) 1102 * @see #fromJson(Reader, Class) 1103 * @see #fromJson(Reader, TypeToken) 1104 */ 1105 @SuppressWarnings("unchecked") 1106 public <T> T fromJson(Reader json, Type typeOfT) throws JsonIOException, JsonSyntaxException { 1107 return (T) fromJson(json, TypeToken.get(typeOfT)); 1108 } 1109 1110 /** 1111 * This method deserializes the JSON read from the specified reader into an object of the 1112 * specified type. This method is useful if the specified object is a generic type. For 1113 * non-generic objects, use {@link #fromJson(Reader, Class)} instead. If you have the JSON in a 1114 * String form instead of a {@link Reader}, use {@link #fromJson(String, TypeToken)} instead. 1115 * 1116 * <p>An exception is thrown if the JSON data has multiple top-level JSON elements, or if there 1117 * is trailing data. Use {@link #fromJson(JsonReader, TypeToken)} if this behavior is not desired. 1118 * 1119 * @param <T> the type of the desired object 1120 * @param json the reader producing JSON from which the object is to be deserialized 1121 * @param typeOfT The specific genericized type of src. You should create an anonymous subclass of 1122 * {@code TypeToken} with the specific generic type arguments. For example, to get the type for 1123 * {@code Collection<Foo>}, you should use: 1124 * <pre> 1125 * new TypeToken<Collection<Foo>>(){} 1126 * </pre> 1127 * @return an object of type T from the Reader. Returns {@code null} if {@code json} is at EOF. 1128 * @throws JsonIOException if there was a problem reading from the Reader 1129 * @throws JsonSyntaxException if json is not a valid representation for an object of type of typeOfT 1130 * 1131 * @see #fromJson(String, TypeToken) 1132 * @see #fromJson(Reader, Class) 1133 * @since 2.10 1134 */ 1135 public <T> T fromJson(Reader json, TypeToken<T> typeOfT) throws JsonIOException, JsonSyntaxException { 1136 JsonReader jsonReader = newJsonReader(json); 1137 T object = fromJson(jsonReader, typeOfT); 1138 assertFullConsumption(object, jsonReader); 1139 return object; 1140 } 1141 1142 private static void assertFullConsumption(Object obj, JsonReader reader) { 1143 try { 1144 if (obj != null && reader.peek() != JsonToken.END_DOCUMENT) { 1145 throw new JsonSyntaxException("JSON document was not fully consumed."); 1146 } 1147 } catch (MalformedJsonException e) { 1148 throw new JsonSyntaxException(e); 1149 } catch (IOException e) { 1150 throw new JsonIOException(e); 1151 } 1152 } 1153 1154 // fromJson(JsonReader, Class) is unfortunately missing and cannot be added now without breaking 1155 // source compatibility in certain cases, see https://github.com/google/gson/pull/1700#discussion_r973764414 1156 1157 /** 1158 * Reads the next JSON value from {@code reader} and converts it to an object 1159 * of type {@code typeOfT}. Returns {@code null}, if the {@code reader} is at EOF. 1160 * 1161 * <p>Since {@code Type} is not parameterized by T, this method is not type-safe and 1162 * should be used carefully. If you are creating the {@code Type} from a {@link TypeToken}, 1163 * prefer using {@link #fromJson(JsonReader, TypeToken)} instead since its return type is based 1164 * on the {@code TypeToken} and is therefore more type-safe. If the provided type is a 1165 * {@code Class} the {@code TypeToken} can be created with {@link TypeToken#get(Class)}. 1166 * 1167 * <p>Unlike the other {@code fromJson} methods, no exception is thrown if the JSON data has 1168 * multiple top-level JSON elements, or if there is trailing data. 1169 * 1170 * <p>The JSON data is parsed in {@linkplain JsonReader#setLenient(boolean) lenient mode}, 1171 * regardless of the lenient mode setting of the provided reader. The lenient mode setting 1172 * of the reader is restored once this method returns. 1173 * 1174 * @param <T> the type of the desired object 1175 * @param reader the reader whose next JSON value should be deserialized 1176 * @param typeOfT The specific genericized type of src 1177 * @return an object of type T from the JsonReader. Returns {@code null} if {@code reader} is at EOF. 1178 * @throws JsonIOException if there was a problem reading from the JsonReader 1179 * @throws JsonSyntaxException if json is not a valid representation for an object of type typeOfT 1180 * 1181 * @see #fromJson(Reader, Type) 1182 * @see #fromJson(JsonReader, TypeToken) 1183 */ 1184 @SuppressWarnings("unchecked") 1185 public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException { 1186 return (T) fromJson(reader, TypeToken.get(typeOfT)); 1187 } 1188 1189 /** 1190 * Reads the next JSON value from {@code reader} and converts it to an object 1191 * of type {@code typeOfT}. Returns {@code null}, if the {@code reader} is at EOF. 1192 * This method is useful if the specified object is a generic type. For non-generic objects, 1193 * {@link #fromJson(JsonReader, Type)} can be called, or {@link TypeToken#get(Class)} can 1194 * be used to create the type token. 1195 * 1196 * <p>Unlike the other {@code fromJson} methods, no exception is thrown if the JSON data has 1197 * multiple top-level JSON elements, or if there is trailing data. 1198 * 1199 * <p>The JSON data is parsed in {@linkplain JsonReader#setLenient(boolean) lenient mode}, 1200 * regardless of the lenient mode setting of the provided reader. The lenient mode setting 1201 * of the reader is restored once this method returns. 1202 * 1203 * @param <T> the type of the desired object 1204 * @param reader the reader whose next JSON value should be deserialized 1205 * @param typeOfT The specific genericized type of src. You should create an anonymous subclass of 1206 * {@code TypeToken} with the specific generic type arguments. For example, to get the type for 1207 * {@code Collection<Foo>}, you should use: 1208 * <pre> 1209 * new TypeToken<Collection<Foo>>(){} 1210 * </pre> 1211 * @return an object of type T from the JsonReader. Returns {@code null} if {@code reader} is at EOF. 1212 * @throws JsonIOException if there was a problem reading from the JsonReader 1213 * @throws JsonSyntaxException if json is not a valid representation for an object of the type typeOfT 1214 * 1215 * @see #fromJson(Reader, TypeToken) 1216 * @see #fromJson(JsonReader, Type) 1217 * @since 2.10 1218 */ 1219 public <T> T fromJson(JsonReader reader, TypeToken<T> typeOfT) throws JsonIOException, JsonSyntaxException { 1220 boolean isEmpty = true; 1221 boolean oldLenient = reader.isLenient(); 1222 reader.setLenient(true); 1223 try { 1224 reader.peek(); 1225 isEmpty = false; 1226 TypeAdapter<T> typeAdapter = getAdapter(typeOfT); 1227 return typeAdapter.read(reader); 1228 } catch (EOFException e) { 1229 /* 1230 * For compatibility with JSON 1.5 and earlier, we return null for empty 1231 * documents instead of throwing. 1232 */ 1233 if (isEmpty) { 1234 return null; 1235 } 1236 throw new JsonSyntaxException(e); 1237 } catch (IllegalStateException e) { 1238 throw new JsonSyntaxException(e); 1239 } catch (IOException e) { 1240 // TODO(inder): Figure out whether it is indeed right to rethrow this as JsonSyntaxException 1241 throw new JsonSyntaxException(e); 1242 } catch (AssertionError e) { 1243 throw new AssertionError("AssertionError (GSON " + GsonBuildConfig.VERSION + "): " + e.getMessage(), e); 1244 } finally { 1245 reader.setLenient(oldLenient); 1246 } 1247 } 1248 1249 /** 1250 * This method deserializes the JSON read from the specified parse tree into an object of the 1251 * specified type. It is not suitable to use if the specified class is a generic type since it 1252 * will not have the generic type information because of the Type Erasure feature of Java. 1253 * Therefore, this method should not be used if the desired type is a generic type. Note that 1254 * this method works fine if any of the fields of the specified object are generics, just the 1255 * object itself should not be a generic type. For the cases when the object is of generic type, 1256 * invoke {@link #fromJson(JsonElement, TypeToken)}. 1257 * 1258 * @param <T> the type of the desired object 1259 * @param json the root of the parse tree of {@link JsonElement}s from which the object is to 1260 * be deserialized 1261 * @param classOfT The class of T 1262 * @return an object of type T from the JSON. Returns {@code null} if {@code json} is {@code null} 1263 * or if {@code json} is empty. 1264 * @throws JsonSyntaxException if json is not a valid representation for an object of type classOfT 1265 * @since 1.3 1266 * 1267 * @see #fromJson(Reader, Class) 1268 * @see #fromJson(JsonElement, TypeToken) 1269 */ 1270 public <T> T fromJson(JsonElement json, Class<T> classOfT) throws JsonSyntaxException { 1271 T object = fromJson(json, TypeToken.get(classOfT)); 1272 return Primitives.wrap(classOfT).cast(object); 1273 } 1274 1275 /** 1276 * This method deserializes the JSON read from the specified parse tree into an object of the 1277 * specified type. This method is useful if the specified object is a generic type. For 1278 * non-generic objects, use {@link #fromJson(JsonElement, Class)} instead. 1279 * 1280 * <p>Since {@code Type} is not parameterized by T, this method is not type-safe and 1281 * should be used carefully. If you are creating the {@code Type} from a {@link TypeToken}, 1282 * prefer using {@link #fromJson(JsonElement, TypeToken)} instead since its return type is based 1283 * on the {@code TypeToken} and is therefore more type-safe. 1284 * 1285 * @param <T> the type of the desired object 1286 * @param json the root of the parse tree of {@link JsonElement}s from which the object is to 1287 * be deserialized 1288 * @param typeOfT The specific genericized type of src 1289 * @return an object of type T from the JSON. Returns {@code null} if {@code json} is {@code null} 1290 * or if {@code json} is empty. 1291 * @throws JsonSyntaxException if json is not a valid representation for an object of type typeOfT 1292 * @since 1.3 1293 * 1294 * @see #fromJson(Reader, Type) 1295 * @see #fromJson(JsonElement, Class) 1296 * @see #fromJson(JsonElement, TypeToken) 1297 */ 1298 @SuppressWarnings("unchecked") 1299 public <T> T fromJson(JsonElement json, Type typeOfT) throws JsonSyntaxException { 1300 return (T) fromJson(json, TypeToken.get(typeOfT)); 1301 } 1302 1303 /** 1304 * This method deserializes the JSON read from the specified parse tree into an object of the 1305 * specified type. This method is useful if the specified object is a generic type. For 1306 * non-generic objects, use {@link #fromJson(JsonElement, Class)} instead. 1307 * 1308 * @param <T> the type of the desired object 1309 * @param json the root of the parse tree of {@link JsonElement}s from which the object is to 1310 * be deserialized 1311 * @param typeOfT The specific genericized type of src. You should create an anonymous subclass of 1312 * {@code TypeToken} with the specific generic type arguments. For example, to get the type for 1313 * {@code Collection<Foo>}, you should use: 1314 * <pre> 1315 * new TypeToken<Collection<Foo>>(){} 1316 * </pre> 1317 * @return an object of type T from the JSON. Returns {@code null} if {@code json} is {@code null} 1318 * or if {@code json} is empty. 1319 * @throws JsonSyntaxException if json is not a valid representation for an object of type typeOfT 1320 * 1321 * @see #fromJson(Reader, TypeToken) 1322 * @see #fromJson(JsonElement, Class) 1323 * @since 2.10 1324 */ 1325 public <T> T fromJson(JsonElement json, TypeToken<T> typeOfT) throws JsonSyntaxException { 1326 if (json == null) { 1327 return null; 1328 } 1329 return fromJson(new JsonTreeReader(json), typeOfT); 1330 } 1331 1332 /** 1333 * Proxy type adapter for cyclic type graphs. 1334 * 1335 * <p><b>Important:</b> Setting the delegate adapter is not thread-safe; instances of 1336 * {@code FutureTypeAdapter} must only be published to other threads after the delegate 1337 * has been set. 1338 * 1339 * @see Gson#threadLocalAdapterResults 1340 */ 1341 static class FutureTypeAdapter<T> extends SerializationDelegatingTypeAdapter<T> { 1342 private TypeAdapter<T> delegate = null; 1343 1344 public void setDelegate(TypeAdapter<T> typeAdapter) { 1345 if (delegate != null) { 1346 throw new AssertionError("Delegate is already set"); 1347 } 1348 delegate = typeAdapter; 1349 } 1350 1351 private TypeAdapter<T> delegate() { 1352 TypeAdapter<T> delegate = this.delegate; 1353 if (delegate == null) { 1354 // Can occur when adapter is leaked to other thread or when adapter is used for (de-)serialization 1355 // directly within the TypeAdapterFactory which requested it 1356 throw new IllegalStateException("Adapter for type with cyclic dependency has been used" 1357 + " before dependency has been resolved"); 1358 } 1359 return delegate; 1360 } 1361 1362 @Override public TypeAdapter<T> getSerializationDelegate() { 1363 return delegate(); 1364 } 1365 1366 @Override public T read(JsonReader in) throws IOException { 1367 return delegate().read(in); 1368 } 1369 1370 @Override public void write(JsonWriter out, T value) throws IOException { 1371 delegate().write(out, value); 1372 } 1373 } 1374 1375 @Override 1376 public String toString() { 1377 return "{serializeNulls:" + serializeNulls 1378 + ",factories:" + factories 1379 + ",instanceCreators:" + constructorConstructor 1380 + "}"; 1381 } 1382 } 1383