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

来源:互联网 发布:网络高清图片大全 编辑:程序博客网 时间:2024/06/05 05:21

==


==

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。 两个没有一点关系。










0 0