首页 > 编程知识 正文

double型转换成string型,java中string转double

时间:2023-05-05 14:34:36 阅读:18687 作者:3122

在gson中将字符串反序列化为Map时,int类型为双精度类型。

原因分析new Gson ().fromJSON )、Map.class; //结果通过查看{'aid':123.0,' aa':11.0}GSON分析过程,gson在TypeAdapter的读取方法中读取字符串值并将其转换为对象:

publictfromjson (jsonreaderreader,类型类型) throws JsonIOException,jsonsyntaxexception { boolean isempty=true; booleanoldlenient=reader.is lenient (; reader.setlenient(true; 类型适配器类型适配器; try { try { reader.peek (; isEmpty=false; typetokenttypetoken=type token.get (typeoft; 类型适配器=this.get adapter (type token; tobject=type adapter.read (reader; Object var8=object; 返回var 8; }catch(eofexceptionvar15 ) if (! isempty (thrownewjsonsyntaxexception ) var15; } catch (illegalstateexceptionvar16 ) thrownewjsonsyntaxexception ) var 16; }catch(ioexceptionvar17 ) thrownewjsonsyntaxexception ) var17; } catch (辅助错误器18 ) thrownewassertionerror (辅助错误器) GSON2.8.5) : ) var18.getmessage ),}类型} finally { reader.set lenient (old lenient ); }返回类型适配器; }而TypeAdapter的类型是在TypeToken中获取的,所有TypeAdapter都存储在gson对下的factories成员变量中,在转换时将转换类型指定为Map.class,key和value默认为ooe

iterator var7=this.factories.iterator (; TypeAdapter candidate; do { if (! var7. hasnext ((thrownewillegalargumentexception ) GSON )2.8.5(cannot handle ) type ); } typeadapterfactoryfactory=(typeadapterfactory ) var7.next ); candidate=factory.create(this,type ); }while(candidate==null ); call.setdelegate(candidate ); this.typetokencache.put(type,candidate; 类型适配器var 10=candidate; 返回var 10; 与该值对应的类型适配器是对象类型a

dapter,而对于NUMBER类型的数据均会识别为double类型。

public Object read(JsonReader in) throws IOException { JsonToken token = in.peek(); switch(token) { case BEGIN_ARRAY: List<Object> list = new ArrayList(); in.beginArray(); while(in.hasNext()) { list.add(this.read(in)); } in.endArray(); return list; case BEGIN_OBJECT: Map<String, Object> map = new LinkedTreeMap(); in.beginObject(); while(in.hasNext()) { map.put(in.nextName(), this.read(in)); } in.endObject(); return map; case STRING: return in.nextString(); case NUMBER: return in.nextDouble(); case BOOLEAN: return in.nextBoolean(); case NULL: in.nextNull(); return null; default: throw new IllegalStateException(); } } 解决方案 重新定义一个TypeAdapter期望来覆盖ObjectTypeAdapter,实现同现有的ObjectTypeAdapter,但是修改Number解析: case NUMBER: String numberStr = in.nextString(); //返回的numberStr不会为null if (numberStr.contains(".") || numberStr.contains("e") || numberStr.contains("E")) { return Double.parseDouble(numberStr); } return Long.parseLong(numberStr);

注册到gson对象中如下:

new GsonBuilder().registerTypeAdapterFactory(ObjectTypeAdapter.FACTORY).create();

运行结果还是将int转换为了double类型。原因是register后的typeAdapter被add到factory的后面,而在查找typeAdater时从前往后遍历,还是找到了之前的ObjectTypeAdapter。

重新定义一个新的类型(gson默认没有的类型)确保查找时会找到创建的adpter:

public final class ObjectTypeAdapter extends TypeAdapter<Object> { private static final Gson gson = new Gson(); private TypeAdapter objectTypeAdapter = gson.getAdapter(Object.class); public Object read(JsonReader in) throws IOException { JsonToken token = in.peek(); switch(token) { case BEGIN_ARRAY: List<Object> list = new ArrayList(); in.beginArray(); while(in.hasNext()) { list.add(this.read(in)); } in.endArray(); return list; case BEGIN_OBJECT: Map<String, Object> map = new LinkedTreeMap(); in.beginObject(); while(in.hasNext()) { map.put(in.nextName(), this.read(in)); } in.endObject(); return map; case STRING: return in.nextString(); case NUMBER: String numberStr = in.nextString(); //返回的numberStr不会为null if (numberStr.contains(".") || numberStr.contains("e") || numberStr.contains("E")) { return Double.parseDouble(numberStr); } return Long.parseLong(numberStr); case BOOLEAN: return in.nextBoolean(); case NULL: in.nextNull(); return null; default: throw new IllegalStateException(); } } public void write(JsonWriter out, Object value) throws IOException { objectTypeAdapter.write(out, value); }}

注册并调用如下,结果成功。

Gson gson = new GsonBuilder().registerTypeAdapter(new TypeToken<Map<String, Object>>(){}.getType(), new ObjectTypeAdapter()).serializeNulls().create(); gson.fromJson("{"aid":123,"aa":11.0}", new TypeToken<Map<String, Object>>(){}.getType());

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。