作者LaPass (LaPass)
看板java
标题Re: [问题] 如何取得 基础型别的 class ?
时间Mon Nov 11 01:03:00 2013
写好了
Gson写得不错,专业的程式设计师写出来的code就是不一样
主要的概念其实也不难
就是树状读JSON物件或是树状读物件的栏位
然後看读到什麽型别,再去依照栏位的型别做处理
基本上跟其他XML解析器之类的架构一样
主要是针对gson对继承之类的处理比较糟糕的缘故
gson跟我找到其他json工具一样,都会把物件型别资料给丢掉
所以,在java to json这一段是ok的
但是 json to java这一段就会出问题
例如有下面这几个 class
package com.f23ko.data;
class A implements IData{
String a;
.....略....
}
class AChild extends A{
String aChild;
.....略....
}
class AList implements IData{
public List<A> alist;
.....略....
}
Gson是看物件栏位的型别在建立实体
所以像这种状况,Gson都没办法把JSON完整的转回来
class Test{
A a=
new AChile();
}
转成JSON再把JSON转回物件时,一定会变成
class Test{
A a=
new A();
}
总之,Gson读到物件的一个栏位时
是这样处理的
1.读到A
↓
A a=
new AChild();
↑
2.呼叫处理A的Adapter去印出JSON
PS.里面有大约有二三十个Adapter在处理各种型别基础型别
然後,如果没有合适的Adapter,Gson会用反射把所有的栏位都去印出来
那段程式码在
com.google.gson.internal.bind.ReflectiveTypeAdapterFactor
在把JSON转成物件时,是这样处理的
1.读到A
↓
A a=
new A();
↑
2.用反射建立A的实体
JSON "a":{"str":"字串","id":..略..}
↑
3.找A的栏位,然後再去找JSON的同名栏位,把值塞进去
如果A没有那个栏位,就不管
我是在JSON里面加个标签去识别物件类型
写个 TypeAdapterFactory 就可以解决了
完全不用修改到Gson的Code就能解决了
总而言之,看例子:
public class Demo
{
public static void main(
String[] args)
{
AList list=
new AList();
list.add(
new A("S1"));
list.add(
new AChild("SC1","SC2"));
System.out.println(list);
//print AList[A{a:S1},AChild{a:SC1,aChild:SC2}]
//problem happen when extends class
Gson gson=new
Gson();
String out=gson.toJson(list);
System.out.println(out);
//print {"alist":[{"a":"S1"},{"aChild":"SC2","a":"SC1"}]}
//That is ok but....
AList list2=gson.fromJson(out,
AList.class);
System.out.println(list2);
//print AList[A{a:S1},A{a:SC1}]
// What happen?
//because of Gson thought that AChile is A
//so that it drop the aChild field
//So I write the FDataTypeAdapterFactory to solve it
//It is similar whith
//com.google.gson.internal.bind.ReflectiveTypeAdapterFactor
//Actually I copy that code and made a little change
Gson fson=
new GsonBuilder()
.registerTypeAdapterFactory(
new FDataTypeAdapterFactory("com.f23ko.data"))
.create();
// or new FDataTypeAdapterFactory(
// "objKey",IData.class,"com.f23ko.data");
//
// objKey is the class Identification in the JSON string
// IData.class is interface to tag the class which you want
// to control
// com.f23ko.data is the data class path
String out2=fson.toJson(list);
System.out.println(out2);
//print
// {
// "objKey":"AList",
// "alist":[
// {"objKey":"A","a":"S1"},
// {"objKey":"AChild","aChild":"SC2","a":"SC1"}]
// }
//objKey had memo the class type
AList list3=fson.fromJson(out2,
AList.
class);
// AList list3=(AList) fson.fromJson(out2, IData.class);
// is also ok
System.out.println(list3);
//print AList[A{a:S1},AChild{a:SC1,aChild:SC2}]
//look! It maintain the class type!
}
}
范例:
http://f23.tw/FFG1.zip
原始码:
http://f23.tw/FFG2.zip
包好的jar:
http://f23.tw/FFG3.zip
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 114.41.101.188
※ 编辑: LaPass 来自: 114.41.101.188 (11/11 01:09)
1F:推 dream1124:推 11/11 08:33
2F:→ swpoker:JSON很随便的~要严谨的要用xml会比较好 11/11 09:04
3F:推 gmoz:感谢分享 11/11 09:59
4F:→ swpoker:其实要去看要注入物件的型态而非在JSON塞标签 11/11 11:34
5F:→ LaPass:如果要严谨的话大概也只能用XML了,但是在javascript中要解 11/11 13:14
6F:→ LaPass:json会方便一些,而且我之前有听过个演讲讲到效率比较的问 11/11 13:17
7F:→ LaPass:题,他们试到後来发现json的效率最好。所以我才选json 11/11 13:19
8F:→ swpoker:json啥都没有~当然效率最好~所以也是我的首选阿~ 11/11 13:46
9F:→ Killercat:xml伔余资料多到靠背... 而且DOM Parser也慢 11/12 12:28
10F:推 PsMonkey:我还比较喜欢 YAML... Zzzz 11/12 13:03
11F:→ Killercat:YAML不错 不过普通来讲JSON的压缩率较好 11/12 17:32
12F:→ jej:自订规则弄成bite code来传输不是更棒~ 弹性高.. 速度快~ 11/12 17:50
13F:→ LaPass:啊对了,那个演讲中也有把binary列入比较,因为binary的溢 11/12 18:37
14F:→ LaPass:出字元的关系,造成资料量变大,反而速度变慢 11/12 18:42
15F:→ LaPass:然後,如果要把JAVA物件转二进位的话,可以用ObjectStream 11/12 19:01
16F:→ LaPass:我不建议用ObjectStream,这样跨语言传输的能力会变很糟糕 11/12 20:57
17F:→ Killercat:那个有严谨protocol 是可以跨语言读的 只是lib要自己找 11/13 09:48
18F:→ LaPass:重点就在那个要找libary.... 11/13 10:58
19F:→ Killercat:说到binary 要跨语言的又要方便又要快 protobuf XD 11/13 12:44
20F:→ LaPass:第一次看到这个东西,有空时我去找来看看 xd 11/13 12:51