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

==


==

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










  • 8
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值