diff --git a/gson/src/main/java/com/google/gson/JsonPrimitive.java b/gson/src/main/java/com/google/gson/JsonPrimitive.java index 365f7bf8..3dad7bae 100644 --- a/gson/src/main/java/com/google/gson/JsonPrimitive.java +++ b/gson/src/main/java/com/google/gson/JsonPrimitive.java @@ -31,6 +31,7 @@ import java.math.BigInteger; * @author Joel Leitch */ public final class JsonPrimitive extends JsonElement { + private static final Class[] PRIMITIVE_TYPES = { int.class, long.class, short.class, float.class, double.class, byte.class, boolean.class, char.class, Integer.class, Long.class, Short.class, Float.class, Double.class, Byte.class, Boolean.class, Character.class }; @@ -154,24 +155,7 @@ public final class JsonPrimitive extends JsonElement { */ @Override public Number getAsNumber() { - return value instanceof String ? stringToNumber((String) value) : (Number) value; - } - - static Number stringToNumber(String value) { - try { - long longValue = Long.parseLong(value); - if (longValue >= Integer.MIN_VALUE && longValue <= Integer.MAX_VALUE) { - return (int) longValue; - } - return longValue; - } catch (NumberFormatException ignored) { - } - - try { - return new BigDecimal(value); - } catch (NumberFormatException ignored) { - return Double.parseDouble(value); // probably NaN, -Infinity or Infinity - } + return value instanceof String ? new LazilyParsedNumber((String) value) : (Number) value; } /** diff --git a/gson/src/main/java/com/google/gson/LazilyParsedNumber.java b/gson/src/main/java/com/google/gson/LazilyParsedNumber.java new file mode 100644 index 00000000..0f5a7ee2 --- /dev/null +++ b/gson/src/main/java/com/google/gson/LazilyParsedNumber.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.google.gson; + +/** + * This class holds a number value that is lazily converted to a specific number type + * + * @author Inderjeet Singh + */ +@SuppressWarnings("serial") +final class LazilyParsedNumber extends Number { + private final String value; + + LazilyParsedNumber(String value) { + this.value = value; + } + + @Override + public int intValue() { + return Integer.parseInt(value); + } + + @Override + public long longValue() { + return Long.parseLong(value); + } + + @Override + public float floatValue() { + return Float.parseFloat(value); + } + + @Override + public double doubleValue() { + return Double.parseDouble(value); + } + + @Override + public String toString() { + return value; + } +} \ No newline at end of file diff --git a/gson/src/main/java/com/google/gson/Streams.java b/gson/src/main/java/com/google/gson/Streams.java index e35236d7..70e01643 100644 --- a/gson/src/main/java/com/google/gson/Streams.java +++ b/gson/src/main/java/com/google/gson/Streams.java @@ -62,7 +62,7 @@ final class Streams { return new JsonPrimitive(reader.nextString()); case NUMBER: String number = reader.nextString(); - return new JsonPrimitive(JsonPrimitive.stringToNumber(number)); + return new JsonPrimitive(new LazilyParsedNumber(number)); case BOOLEAN: return new JsonPrimitive(reader.nextBoolean()); case NULL: diff --git a/gson/src/test/java/com/google/gson/functional/ArrayTest.java b/gson/src/test/java/com/google/gson/functional/ArrayTest.java index facc676a..a7808dc2 100644 --- a/gson/src/test/java/com/google/gson/functional/ArrayTest.java +++ b/gson/src/test/java/com/google/gson/functional/ArrayTest.java @@ -206,12 +206,13 @@ public class ArrayTest extends TestCase { } public void testArrayOfPrimitivesAsObjectsDeserialization() throws Exception { - String json = "[1,'abc',0.3,5]"; + String json = "[1,'abc',0.3,1.1,5]"; Object[] objs = gson.fromJson(json, Object[].class); - assertEquals(1, objs[0]); + assertEquals(1, ((Number)objs[0]).intValue()); assertEquals("abc", objs[1]); - assertEquals(new BigDecimal("0.3"), objs[2]); - assertEquals(5, objs[3]); + assertEquals(0.3, ((Number)objs[2]).doubleValue()); + assertEquals(new BigDecimal("1.1"), new BigDecimal(objs[3].toString())); + assertEquals(5, ((Number)objs[4]).shortValue()); } public void testArrayOfObjectsWithoutTypeInfoDeserialization() throws Exception { diff --git a/gson/src/test/java/com/google/gson/functional/ParameterizedTypesTest.java b/gson/src/test/java/com/google/gson/functional/ParameterizedTypesTest.java index 9c12ebd3..2fe1c76c 100644 --- a/gson/src/test/java/com/google/gson/functional/ParameterizedTypesTest.java +++ b/gson/src/test/java/com/google/gson/functional/ParameterizedTypesTest.java @@ -127,7 +127,7 @@ public class ParameterizedTypesTest extends TestCase { MyParameterizedType src = new MyParameterizedType(10); String json = MyParameterizedTypeAdapter.getExpectedJson(src); MyParameterizedType intTarget = gson.fromJson(json, ptIntegerType); - assertEquals(10, (int) intTarget.value); + assertEquals(10, ((Number)intTarget.value).intValue()); MyParameterizedType srcStr = new MyParameterizedType("abc"); json = MyParameterizedTypeAdapter.getExpectedJson(srcStr);