如何获得返回类型是泛型T的具体类型?

牧之~ 2018-07-20 05:24:44

/**
* 将json字符串反转为类型T
*/
@SuppressWarnings("unchecked")
public static <T> T parseObject(String jsonString)
{
// 这里编译报错
if (T.class = String.class)
{
return (T)jsonString;
}

T t = JSON.parseObject(jsonString, new TypeReference<T>()
{
});

return t;

}

我写了个jsonutil供redis操作用,JSON工具是fastjson,基本思路是json话。 set 方法是把任意类型转为json,如果本身是字符串不做处理。那么get方法就是逆向的过程,如果本身是字符串的话也不需要处理,直接返回。

这里有个难点就是你无法知道入参是纯字符串或者对象序列化后的,所以我想通过泛型T来判断。我试了用fastjson的
new TypeReference<T>() { }.getType() == new TypeReference<String>() { }.getType() 判断,结果失败,前者打印了下得到的type还是T,参考这个帖子https://blog.csdn.net/changsa65/article/details/78790881得到的也是T。

整个调用过程是这样的

1 业务代码 String s = cache.get("food");
2 缓存客户端

/**
* 返回 key 所关联的字符串值。 如果 key 不存在那么返回特殊值 nil 。
*/
@SuppressWarnings("unchecked")
@Override
public <T> T get(String key)
{
if (StringUtils.isBlank(key))
{
return null;
}

ShardedJedis jedis = RedisCacheFactory.getInstance().getResource(cluster);

try
{
return (T)JSONUtil.parseObject(jedis.get(key));
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
jedis.close();
}

return null;
}

3 就是json的工具类了,卡在判断类型那里。也就是说泛型T从第一部调用那里确定下来,到了第三步是丢失了还是无法不好获取?

之所以纯字符串直接放进去,是因为fastjson处理过后会带双引号,双引号成了字符串的一部分,那么数字字符串就无法incr操作了。
...全文
1662 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
大泼猴 2019-01-19
  • 打赏
  • 举报
回复
用Object接受
然后用 instanceof 判断是哪一个类,再去走对应的类逻辑
牧之~ 2018-07-24
  • 打赏
  • 举报
回复
引用 9 楼 maradona1984 的回复:
类的泛型好获取,方法的你这种没办法
其实我觉得你可以取出字符串,然后判断是否json来决定是否反序列化

恩,本来的目的其实是写一套get set方法,支持所有类型,且有些类型的其他方法可以有效使用(比如String 的append),后来发现此路不通。
还是拆了接口,String本来是redis的五大类型之一,String的接口单独封装了,订下开发规范,其他的走泛型接口,暂时不再过多设计了。
牧之~ 2018-07-23
  • 打赏
  • 举报
回复
引用 7 楼 frank_lee_cn 的回复:
竟然不能更改上面的答案,唉!

[quote=引用 1 楼 zssazrael 的回复:]
public static <T> T parseObject(String jsonString)
public <T> T get(String key)
这本身的写法就是错误的。


这写法没错,真有这种语法:

public static <T> T parseObject(String jsonString, Class<T> cls){
Object o = newInstance(cls);
.....
return (T)o;
}
以一个参数,将类型传给它
例如:
Test test = JSON.parseObject(String jsonString, Test.class);//这里修正上面回答的错误
这样就行了

[/quote]

这个值得考虑,当初不想让传递参数就是怕调用方麻烦,才用的上面的方案。
maradona1984 2018-07-23
  • 打赏
  • 举报
回复
类的泛型好获取,方法的你这种没办法
其实我觉得你可以取出字符串,然后判断是否json来决定是否反序列化
Frank6600 2018-07-22
  • 打赏
  • 举报
回复
竟然不能更改上面的答案,唉!

引用 1 楼 zssazrael 的回复:
public static <T> T parseObject(String jsonString)
public <T> T get(String key)
这本身的写法就是错误的。


这写法没错,真有这种语法:

public static <T> T parseObject(String jsonString, Class<T> cls){
Object o = newInstance(cls);
.....
return (T)o;
}
以一个参数,将类型传给它
例如:
Test test = JSON.parseObject(String jsonString, Test.class);//这里修正上面回答的错误
这样就行了

Frank6600 2018-07-22
  • 打赏
  • 举报
回复
public static <T> T parseObject(String jsonString, Class<T> cls){
}
这样就行了
Frank6600 2018-07-22
  • 打赏
  • 举报
回复
以一个参数,将类型传给它
例如:
Test test = JSON.parseObject(String jsonString, test.getClass());
幽饮烛 2018-07-21
  • 打赏
  • 举报
回复
按照这种写法,调用 parseObject 方法地方能用只能用Object类型变量接收返回值。
在方法级声明了泛型<T>,那么T的具体类型只能在调用方法时传入,但写的方法又没有传入具体T的类型,所以这里的 T 没意义,还不如直接返回 String。
牧之~ 2018-07-20
  • 打赏
  • 举报
回复
引用 1 楼 zssazrael 的回复:
public static <T> T parseObject(String jsonString)
public <T> T get(String key)
这本身的写法就是错误的。
用 <T> 定义了 T 却没有传入具体类型,调用的地方只能用 Object 接收。方法内也不能得知T的具体类型。
如果是 类定义了<T>,方法要用到 T,不能在方法覆盖<T>
比如:public T get(String key)

静态方法不能用类的<T>,所以 public static <T> T parseObject(String jsonString) 没有意义。


<T> T 用返回类型定义泛型T,这个T的具体类型得一级一级往上找,最终可定能确定下来,我觉得有意义,也用到了。
牧之~ 2018-07-20
  • 打赏
  • 举报
回复

/**
* 将json字符串反转为类型T,纯字符串(不包含"@type")原样返回。</br>
* 使用TypeReference<T>泛型反序列化的JSONString必然带@type
*/
@SuppressWarnings("unchecked")
public static <T> T parseObject(String jsonString)
{
if (!jsonString.contains("@type"))
{
return (T)jsonString;
}

T t = JSON.parseObject(jsonString, new TypeReference<T>()
{
});

return t;
}

现在暂时用硬编码做的。
幽饮烛 2018-07-20
  • 打赏
  • 举报
回复
public static <T> T parseObject(String jsonString)
public <T> T get(String key)
这本身的写法就是错误的。
用 <T> 定义了 T 却没有传入具体类型,调用的地方只能用 Object 接收。方法内也不能得知T的具体类型。
如果是 类定义了<T>,方法要用到 T,不能在方法覆盖<T>
比如:public T get(String key)

静态方法不能用类的<T>,所以 public static <T> T parseObject(String jsonString) 没有意义。

62,628

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧