V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Renco
V2EX  ›  Java

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

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

    ![这是图片 1]( https://meee.com.tw/R8cfkNx "这是图片 1")
    ![这是图片 2]( https://meee.com.tw/KLKSVhy "这是图片 2")
    ftsland
        11
    ftsland  
       10 天前
    MD 不知道为啥发不出来, 如果需要 Cache 里面是任意类型, 不要使用 CacheHelper<K, V> , 使用 CacheHelper<K> , Cache 用 Cache<K,Object> getByKey 去掉 class 参数,
    Renco
        12
    Renco  
    OP
       10 天前
    @ftsland #11 好,我试试,谢谢!
    bli22ard
        13
    bli22ard  
       10 天前
    建议
    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
        14
    xiangbohua  
       10 天前
    好像不是因为范形擦除的原因,我觉得还是因为类上面定义的类型是 V ,但是方法上传的是 T ,T 和 V 之间又没有范性约束那么直接理解为两个不相关的类就好了。既然不相关,那编译器只能认为返回的是 object (拿不到任何类型限定信息)。
    如果有错误可指出
    ajieggoto318
        15
    ajieggoto318  
       10 天前
    如果 T 是 V 的父类可以把 getByKey 方法的<T>改为<T super V>,然后代码好像没有问题,重启一下 idea ,看看是不是 idea 抽风了
    jaredyam
        16
    jaredyam  
       10 天前
    看起来是 IDEA 缓存的问题
    yazinnnn0
        17
    yazinnnn0  
       10 天前


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

    kotlin 的范型和类型推断好很多, 所以有人(我)说 kotlin 是 java 和 ocaml 的结合体, 现代语言的牛逼的类型推断能力都是从 ml 系语言里借鉴来的(点草 rust 批)
    635925926
        18
    635925926  
       10 天前
    把 T 换成 V
    ychost
        19
    ychost  
       10 天前
    应该是 IDEA 的问题,清空缓存重试下,
    dragondove
        20
    dragondove  
       10 天前
    @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();
    }
    }
    ```
    entrance
        21
    entrance  
       10 天前
    cacheHelper 注入时没指定泛型类型,可以试下这样: cacheHelper<String, List<String>> cacheHelper
    DOLLOR
        22
    DOLLOR  
       10 天前
    @yazinnnn0
    是泛型,不是范型。generic 是通用、泛用之义。
    ChenFanlin
        23
    ChenFanlin  
       10 天前
    简单写了个小 demo 试了下,好像也没报错?
    ```
    public class Test {
    public static void main(String[] args) {
    Helper<String, Integer> helper = new Helper<>();
    Key key = helper.getByKey("", "", Key.class);
    System.out.println(key);
    }

    private static class Key {
    }

    private static class Helper<K, V> {
    public <T> T getByKey(String cacheKey, K key, Class<T> tClass) {
    return null;
    }
    }
    }
    ```
    levintrueno
        24
    levintrueno  
       10 天前
    看看你的 cacheHelper 注入的时候是怎么定义的,如果 key 都是 String ,那么可以 @Resource CacheHelper<String, ?> cacheHelper; 那个 vClass 参数也可以不用了,应该可以直接返回你定义的类型。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2161 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 01:14 · PVG 09:14 · LAX 17:14 · JFK 20:14
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.