您的位置:首页 > Web前端

JackJson反序列化为何一定需要TypeReference

2015-09-09 20:43 423 查看
==

==
import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

public class TestJackson {
public static ObjectMapper mapper = new ObjectMapper();
public static ObjectMapper mapper1 = new ObjectMapper();
public static void main(String[] args) throws Exception {
List<Person> listPerson = new ArrayList<>();
listPerson.add(new Person("张三1"));
listPerson.add(new Person("张三2"));
String jsonPerson = mapper.writeValueAsString(listPerson);
// [{"name":"张三1"},{"name":"张三2"}]
System.out.println(jsonPerson);
// 现在我要用jsonPerson还原
List<Person> getlistPerson = mapper1.readValue(jsonPerson,
new TypeReference<List<Person>>() {
});
System.out.println(getlistPerson.get(0).name);
}
}
class Person {
public Person(){
}
public String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}


这是一个Jackson json的例子。

==

首先说泛型类。比如说我们平时使用的HashMap,类的定义是 public class HashMap<K,V> 这里的K V就是两个泛型,

如果要使用HashMap就需要指定泛型的实际类型。比如说 new HashMap<String,String>,

① 对于类的定义,也就是HashMap的制作角度讲,使用了K V字符后,便可以使用KV这两个字符,但是只能存在声明和引用的使用,而不能实例化。

② 对于类的使用来说,比如 HashMap<String,String> hashmap= new HashMap<String,String>,之后便可以使用所以定义的方法,此时put和get 所对应的KV必须一致。

如果是其他类,子类也是可以的。比如 List<Person> 之后,add方法可以存放Person的子类,get后也被Person所引用。不需转化。

如果是泛型方法的定义,

比如:

public <T> T add(T t){

return null;

}

这里的T已经和类无关了,这里的T对应的是 Person p=new ClassName().add(new Person()) 这里public后面<T>这里的T限定了后面的返回类型必须是T,参数也必须是T,尖括号里面的T来自于Person p 这里的Person p,也就是说因为 这里的Person导致了<T>的对应关系,于是乎 add方法的参数和返回值必须是Person。 当然add函数的返回和参数也可以不是T。

泛型擦除讲的是什么:

山面的①和②中①是定义 ②是声明,泛型擦除讲的是擦除② 而不是①。

比如说 List<Person> list=new ArrayList<>(); 这个语句经过编译后会成为 List list=new Arraylist(); 这样的语句。

但是 如果是class<T> Cname{ } 这个类经过编译之后,所有的信息都还在。

==

public class R {

public static void main(String[] args) {
TClass t = new TClass<String>() {};
//TClass<java.lang.String>
System.out.println(t.getClass().getGenericSuperclass());
}
}
class TClass<T> {
}


==

这里获取到了//TClass<java.lang.String>

这个代码其实是

public class R {

public static void main(String[] args) {
TClass t = new InnerTClass();
System.out.println(t.getClass().getGenericSuperclass());
}
}
class TClass<T> {
}
class InnerTClass extends TClass<String>{

}


==

这里的两个代码等价了。根据superclass获取到了type的类型。Jackson就是以这个type为框架实现的类实例化。在InnerClass中泛型已经是被使用者而不是定义者了。

这里的String的意思是 java.lang.String

如果代码是

class TClass<T> {

}

class InnerTClass<String> extends TClass<String> {

}

这样的形式的话,那么对于这里的两个String 都是定义 ,不是使用,也就是说这里的两个String都和T是一个意思,而不是java.lang.Sting那个String。 两个没有一点关系。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: