阅读更多
1 代码清单
OuterEntity:第一级
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| package org.liuyehcf.fastjson.entity;
public class OuterEntity<T> { private int id;
private String name;
private T middleEntity;
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public T getMiddleEntity() { return middleEntity; }
public void setMiddleEntity(T middleEntity) { this.middleEntity = middleEntity; } }
|
MiddleEntity:第二级
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| package org.liuyehcf.fastjson.entity;
public class MiddleEntity<T> { private int id;
private String name;
private T innerEntity;
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public T getInnerEntity() { return innerEntity; }
public void setInnerEntity(T innerEntity) { this.innerEntity = innerEntity; } }
|
InnerEntity:第三级
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| package org.liuyehcf.fastjson.entity;
public class InnerEntity { private int id;
private String name;
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; } }
|
测试代码
- 将Java对象转化为Json字符串
- 将Json字符串,配合类型信息,转化为Java对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| package org.liuyehcf.fastjson;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference; import org.liuyehcf.fastjson.entity.InnerEntity; import org.liuyehcf.fastjson.entity.MiddleEntity; import org.liuyehcf.fastjson.entity.OuterEntity;
public class FastJsonDemo { public static void main(String[] args) { OuterEntity<MiddleEntity<InnerEntity>> outerEntity = new OuterEntity<>(); MiddleEntity<InnerEntity> middleEntity = new MiddleEntity<>(); InnerEntity innerEntity = new InnerEntity();
innerEntity.setId(1); innerEntity.setName("InnerEntity");
middleEntity.setId(2); middleEntity.setName("middleEntity"); middleEntity.setInnerEntity(innerEntity);
outerEntity.setId(3); outerEntity.setName("outerEntity"); outerEntity.setMiddleEntity(middleEntity);
String json = JSON.toJSONString(outerEntity);
System.out.println(json);
OuterEntity<MiddleEntity<InnerEntity>> parsedOuterEntity = JSON.parseObject( json, new TypeReference<OuterEntity<MiddleEntity<InnerEntity>>>() { });
System.out.println(parsedOuterEntity.getMiddleEntity().getClass().getName()); System.out.println(parsedOuterEntity.getMiddleEntity().getInnerEntity().getClass().getName());
} }
|
输出如下
1 2 3
| {"id":3,"middleEntity":{"id":2,"innerEntity":{"id":1,"name":"InnerEntity"},"name":"middleEntity"},"name":"outerEntity"} org.liuyehcf.fastjson.entity.MiddleEntity org.liuyehcf.fastjson.entity.InnerEntity
|
能够解析多级泛型的关键语句是:new TypeReference<OuterEntity<MiddleEntity<InnerEntity>>>() {}
2 Java如何保留编译期的泛型信息
Java中的泛型的实现方式是擦除。也就是说,所有包含不同泛型参数的类型共享着同一个.class文件,或者Class对象。很显然,这个Class对象或者.class文件中必然不会存有泛型参数的信息(已经被擦除了)
Java采用另外一种方式来存储泛型信息,对于一个类型C而言,沿着继承链路往上走,其直接父类F到根基类Object,这条链路上的所有泛型信息都是确定的(指定了或者未指定)
- C1的直接父类是
ArrayList<String>
,泛型参数为String
- C2的直接父类是
ArrayList
,泛型参数未指定,其实也就是Object
1 2 3 4 5 6 7
| class C1 extends ArrayList<String> { ... }
class C2 extends ArrayList {
}
|
由于类型的定义在编译期就已经确定了,因此Java能够通过某种机制将继承链路上的类型信息(包括指定了的泛型参数)保存下来。具体来说,Class包含如下方法,该方法可以获取直接父类的信息(Type对象),该对象包含了泛型参数等信息
1
| public Type getGenericSuperclass()
|
2.1 示例代码
泛型类型MyTypeReference,将其设置为抽象类,避免实例化。在构造方法中初始化type字段,即泛型参数。其中getClass()方法具有多态性质
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| package org.liuyehcf.fastjson;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type;
public abstract class MyTypeReference<T> { private final Type type;
public MyTypeReference() { Type superClass = getClass().getGenericSuperclass();
Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0];
this.type = type; }
public final Type getType() { return type; } }
|
测试代码。注意大括号,即创建子类,但是不重写任何方法。输出为java.util.List<java.util.List<java.lang.String>>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| package org.liuyehcf.fastjson;
import java.util.List;
public class GenericTypeDemo<T> {
public static void main(String[] args) { System.out.println( new MyTypeReference<List<List<String>>>() { }.getType().getTypeName()); } }
|