作为我正在创建的API的一部分,我已经允许配置的规范(它可以是任何存储格式,只有一个实现是使用Json)。作为其中的一部分,我的代码将不知道配置的真正内容。我正在使用Gson库来读取json实现的配置,但是在处理数字时遇到了一个障碍。我的当前代码使用递归读取内部对象,并包含以下内容:
private JsonConfigurationSection readObject(JsonReader in) throws IOException {
JsonConfigurationSection section = new JsonConfigurationSection();
in.beginObject();
while (in.peek() != JsonToken.END_OBJECT) {
String name = in.nextName();
switch (in.peek()) {
case BEGIN_OBJECT: {
section._internal.put(name, readObject(in));
}
break;
case BEGIN_ARRAY: {
in.beginArray();
List<String> array = new LinkedList<>();
while (in.peek() != JsonToken.END_ARRAY) {
array.add(in.nextString());
}
in.endArray();
section._internal.put(name, array);
}
break;
case BOOLEAN: {
boolean next = in.nextBoolean();
section._internal.put(name, next);
}
break;
case NUMBER: {
//read the next number, whether long, int, or double
section._internal.put(name, next);
}
break;
case STRING: {
String next = in.nextString();
section._internal.put(name, next);
}
break;
}
}
in.endObject();
}JsonConfigurationSection类只是地图的包装器:
class JsonConfigurationSection implements ConfigurationSection {
final Map<String, Object> _internal = new TreeMap<>();
//methods being inherited, just getters for data from the map
}配置的一个示例可能是
{
"server": {
"ip": "127.0.0.1",
"port": 3306
}
"someval": 33.4
}出现的问题是,JsonReader只为"Number“提供下一个令牌,然后为长、双和int提供特定的getter。
在不丢失数据和使用“最佳”存储空间的情况下,获得该数字的最佳方法是什么?(我愿意放弃多头,但我更愿意看看我是否能保持它们的一致性)
发布于 2015-03-04 16:12:30
在玩了一会儿之后,似乎最好的方法是使用nextString并使用BigDecimal,就像评论中建议的那样:
String line = in.nextString();
BigDecimal decimal = new BigDecimal(line);
try {
section._internal.put(name, decimal.intValueExact());
} catch (ArithmeticException e) {
try {
section._internal.put(name, decimal.longValueExact());
} catch (ArithmeticException ex) {
section._internal.put(name, decimal.doubleValue());
}
}这实际上只是检查该值是否适合于int (这是3种类型中最有限的),然后是长,如果失败,则保持为双值。
发布于 2015-03-03 17:43:04
很抱歉把它作为回答。没有足够的声誉来添加评论。
所以。就像想法一样。您可以扩展java.lang.Number,并在字符串中保留“原样”的值。
https://stackoverflow.com/questions/28837382
复制相似问题