1.問題背景
知道方法的Method和方法的響應字符串,將字符串轉換爲returnType。Method可能包含多級泛型
2.核心內容
method.getGenericReturnType 獲取方法返回類型泛型類
ParameterizedTypeImpl 記錄泛型嵌套關係
3.基本思路
先利用getGenericReturnType 獲取方法返回類型泛型類,然後對返回的Type做判斷,分兩部分進行處理。核心代碼如下:
public static Object transfer1(String req,String className,String methodName ) throws Exception{
Class clazz=Class.forName(className);
Method method=clazz.getDeclaredMethod(methodName);
Type type=method.getGenericReturnType();
if(type instanceof ParameterizedType){
ParameterizedType type1=(ParameterizedType) type;
ParameterizedTypeImpl beforeType = new ParameterizedTypeImpl(type1.getActualTypeArguments(), type1.getOwnerType(),type1.getRawType());
return JSON.parseObject(req,beforeType);
}else{ //沒有泛型
return JSON.parseObject(req,(Class)type);
}
}
4.測試
泛型類Result ,使用了lombok插件
package com.design.pattern.generic;
import lombok.Data;
@Data
public class Result<T> {
private int ret;
private String msg;
private T data;
// 此處省略getter和setter方法
}
泛型類 Item
package com.design.pattern.generic;
import lombok.Data;
@Data
public class Item<T> {
private String name;
private String value;
T t;
// 此處省略getter和setter方法
}
測試類:Test
package com.design.pattern.generic;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.util.ParameterizedTypeImpl;
import lombok.extern.slf4j.Slf4j;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.*;
@Slf4j
public class Test {
public Result<Item<String>> getRoushan(){
return null;
}
public Result<List<String>> getRoushan1(){
return null;
}
public Result getRoushan2(){
return null;
}
private <T> ResponseEntity<Map<String, T>> getRoushan3() {
String json = "{\"code\":\"1\",\"msg\":\"Success\",\"data\":{\"orderid1\":{\"address\":\"street 1\",\"pay\":\"111.0\",\"productId\":\"1342546\"}}}";
return null;
//return JSONObject.parseObject(json, new TypeReference<ResponseEntity<Map<String, T>>>(){});
}
public static void main(String[] args) throws Exception{
//getRoushan
Item<String> item=new Item<>();
item.setName("dddd");
item.setValue("ddd");
item.setT("bbb");
log.info(JSON.toJSONString(item));
Result<Item<String>> result=new Result<>();
result.setMsg("111");
result.setRet(00);
result.setData(item);
log.info(JSON.toJSONString(result));
String resultStr=JSON.toJSONString(result);
//getRoushan1
List<String> list=new ArrayList<>();
list.add("1111");
list.add("2222");
list.add("3333");
Result<List<String>> result2=new Result<>();
result2.setMsg("111");
result2.setRet(00);
result2.setData(list);
Result<List<String>> ret1=
(Result<List<String>>) transfer1(JSON.toJSONString(result2),"com.design.pattern.generic.Test","getRoushan1");
log.info("hold");
//getRoushan1 end
////getRoushan3
Result result3=new Result<>();
result3.setMsg("111");
result3.setRet(00);
Result ret2=
(Result) transfer1(JSON.toJSONString(result3),"com.design.pattern.generic.Test","getRoushan2");
log.info("hold");
//
String json = "{\"code\":\"1\",\"msg\":\"Success\",\"data\":{\"orderid1\":{\"address\":\"street 1\",\"pay\":\"111.0\",\"productId\":\"1342546\"}}}";
ResponseEntity<Map<String, Map>> ret=(ResponseEntity<Map<String, Map>>)transfer1(json,"com.design.pattern.generic.Test","getRoushan3");
log.info("hold");
}
//不能直接拿來用
//Exception in thread "main" java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl cannot be cast to com.alibaba.fastjson.util.ParameterizedTypeImpl
public static Object transfer1(String req,String className,String methodName ) throws Exception{
Class clazz=Class.forName(className);
Method method=clazz.getDeclaredMethod(methodName);
Type type=method.getGenericReturnType();
if(type instanceof ParameterizedType){
ParameterizedType type1=(ParameterizedType) type;
ParameterizedTypeImpl beforeType = new ParameterizedTypeImpl(type1.getActualTypeArguments(), type1.getOwnerType(),type1.getRawType());
return JSON.parseObject(req,beforeType);
}else{ //沒有泛型
return JSON.parseObject(req,(Class)type);
}
}
}
5.可能的遺留問題
如果不停的new ParameterizedTypeImpl 可能會造成內存泄露,基本解決思路就是把Type用ConcurrentHashMap緩存起來
具體可參考下面兩篇文章:
https://www1350.github.io/hexo/post/bc931ae8.html
https://www.jianshu.com/p/adfde1a318b0
6.相關的源碼已經傳至git