请教一下关于 Java 泛型的问题。

2024 年 12 月 11 日
 Renco

https://i.imgur.com/l4fWhJU.png https://i.imgur.com/g9tXoSW.png

5609 次点击
所在节点    Java
24 条回复
Renco
2024 年 12 月 11 日
Renco
2024 年 12 月 11 日
Renco
2024 年 12 月 11 日
为啥这样写,返回的值默认是 Object ,而不是参数中的 EqpProdInfo 类。
Renco
2024 年 12 月 11 日
泛型平时用的比较少,这次写新功能的时候,尝试用用,遇上了这个错。
tars13344
2024 年 12 月 11 日
看你 getKey 方法的 tclass 参数也没有用到,如果只是想用来指定返回值类型的话 是不需要这个参数的,在调用的时候直接 cache.<EqpProdInfo>getIfPresent() 就可以了
tars13344
2024 年 12 月 11 日
@tars13344 #5 额 最后一句有符号被 md 语法吃掉了
```java
cacheHelper.<EqpProdInfo>geBykey()
```
tars13344
2024 年 12 月 11 日
@tars13344 #5 ...这个符号是打不出来了,总之就是在调用函数的时候 在函数名和. 之间用尖括号包围指定 T 的类型即可
Renco
2024 年 12 月 11 日
@tars13344 #7 谢谢,忘记了泛型可以这样写,不过这个依旧会报错,返回类型一直是 Object
w11ya
2024 年 12 月 11 日
泛型擦除
ftsland
2024 年 12 月 11 日
你是想 Cache 里面 Value 可以保存任意类型吗?

![这是图片 1]( https://meee.com.tw/R8cfkNx "这是图片 1")
![这是图片 2]( https://meee.com.tw/KLKSVhy "这是图片 2")
ftsland
2024 年 12 月 11 日
MD 不知道为啥发不出来, 如果需要 Cache 里面是任意类型, 不要使用 CacheHelper<K, V> , 使用 CacheHelper<K> , Cache 用 Cache<K,Object> getByKey 去掉 class 参数,
Renco
2024 年 12 月 11 日
@ftsland #11 好,我试试,谢谢!
bli22ard
2024 年 12 月 11 日
建议
public <T extends V> T get(String cacheKey,K key){
Cache<K,V> cache=cacheMap.get(cacheKey);
if(cache!=null){
return (T) cache.get(key);
}
return null;
}

你是要限定 V 的类型范围,因为你已经限定了 cache 的 value 是个 V 类型。传 Class<T> clazz , 那你的 V 类型还不如直接定义为 Object 。另外你的成员变量 cacheMap 会有并发安全问题,当然如果 CacheHelper 不会有并发问题,那可以忽略并发安全问题
xiangbohua
2024 年 12 月 11 日
好像不是因为范形擦除的原因,我觉得还是因为类上面定义的类型是 V ,但是方法上传的是 T ,T 和 V 之间又没有范性约束那么直接理解为两个不相关的类就好了。既然不相关,那编译器只能认为返回的是 object (拿不到任何类型限定信息)。
如果有错误可指出
ajieggoto318
2024 年 12 月 11 日
如果 T 是 V 的父类可以把 getByKey 方法的<T>改为<T super V>,然后代码好像没有问题,重启一下 idea ,看看是不是 idea 抽风了
jaredyam
2024 年 12 月 11 日
看起来是 IDEA 缓存的问题
yazinnnn0
2024 年 12 月 11 日


调用方法的时候标一下范型的具体类型, java 的语法比较弱鸡, 没办法根据返回值的接收类型来推断范型的类型, 也没办法像 kotlin 的 inline+refied 那样获取范型的具体类型

kotlin 的范型和类型推断好很多, 所以有人(我)说 kotlin 是 java 和 ocaml 的结合体, 现代语言的牛逼的类型推断能力都是从 ml 系语言里借鉴来的(点草 rust 批)
635925926
2024 年 12 月 11 日
把 T 换成 V
ychost
2024 年 12 月 11 日
应该是 IDEA 的问题,清空缓存重试下,
dragondove
2024 年 12 月 11 日
@yazinnnn0 根据返回类型实际上是放弃类型安全,不过可以通过其他方式补全(比如楼主用的 Class<T>的方式,但是 Class<T> 存在 T 不能有泛型的限制,都是历史债,建议是自己定义一个 TypeInfo 之类的类型来使用),下面的例子是 java 中根据返回类型推断泛型的例子,java 在这方面不存在你说的问题。

```java
public class Main {
static Object o = new Object();
@SuppressWarnings("unchecked")
static <T> T get() {
return (T) o;
}
public static void main(String[] args) {
String x = get();
}
}
```

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://v2ex.xtra.eu.org/t/1096648

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX