这样的泛型定义到底如何调用才是对的呢? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
abcbuzhiming
V2EX    Java

这样的泛型定义到底如何调用才是对的呢?

  •  
  •   abcbuzhiming Jan 2, 2018 2937 views
    This topic created in 3038 days ago, the information mentioned may be changed or developed.
    public class Abc<T>{ private final JavaType javaType; public Abc(Class<T> type) { this.javaType = getJavaType(type); } } 

    我调用的时候

    Abc<HashSet<String>> Abc = new Abc<HashSet<String>>(HashSet<String>.class); 

    通不过,报错

    Abc<HashSet<String>> Abc = new Abc<HashSet<String>>(HashSet.class); 

    还是报错

    Abc<HashSet> Abc = new Abc<HashSet>(HashSet.class); 

    这样终于可以了,但是没有指定 HashSet 容器内部的类型,IDE 报警,而且我也觉得这好像不是正统的 java 写法,正统的 java 写法都应该指定容器里的类型的。

    我查了不少资料,看起来最后一种才是对的,但是为啥最后一种那么别扭呢

    12 replies    2018-01-03 20:55:43 +08:00
    lhx2008
        1
    lhx2008  
       Jan 2, 2018
    这个应该是泛型的类型擦除导致的吧,Class 是没有泛型的,HashSet<String>的 Class 是 HashSet 不是 HashSet<String>
    abcbuzhiming
        2
    abcbuzhiming  
    OP
       Jan 2, 2018
    @lhx2008 我知道 java 这玩意存在泛型擦除问题,但是奇怪的是,第二种写法也不对,第三种对了吧,但是 IDE 会报警说你没给容器指定元素的类型,感觉也不正统,所以我想知道这里正统的想法到底是啥
    lhx2008
        3
    lhx2008  
       Jan 2, 2018
    @abcbuzhiming
    IDE 报警用 @SuppressWarnings("unchecked")抑制就好,或者把 Class<T>的<T>去掉
    因为 HashSet<String>.class 的写法是语法错误的,所以只能写 HashSet.class,Class 是 HashSet
    然后,
    T 就是 HashSet,不是 HashSet<String>了,所以要 Abc<HashSet>
    zhx1991
        4
    zhx1991  
       Jan 2, 2018
    感觉你需要的是 ? 而不是 T
    abcbuzhiming
        5
    abcbuzhiming  
    OP
       Jan 2, 2018
    @lhx2008 那为什么第二写法是错的呢?
    Abc<HashSet<String>> Abc = new Abc<HashSet<String>>(HashSet.class);
    icegreen
        6
    icegreen  
       Jan 2, 2018
    如果你更关心容器内部的类型, 就把 String 当做参数传进去吧. 或者传 HashSet 和 String 两个参数?

    不了解业务场景, 无法给出准确建议~~.
    abcbuzhiming
        7
    abcbuzhiming  
    OP
       Jan 2, 2018
    @icegreen 你没弄懂我的意思,这无关业务场景,而是 java 的泛型参数到底该如何使用的问题,如果我传入的是一个容器类型该如何使用,java 本身都是推荐在使用容器类型是指明容器元素类型的,但是这里明显有矛盾
    finull
        8
    finull  
       Jan 2, 2018
    只用过 C# 的泛型,不理解这个类名称定义中已经有`T`了,为什么还要在构造函数中再穿个`Class<T>`进去
    iEverX
        9
    iEverX  
       Jan 2, 2018
    @abcbuzhiming 因为 HashSet<String> 和 HashSet 的类型不一样啊
    iEverX
        10
    iEverX  
       Jan 2, 2018
    类似的需求,可以用 TypeReference
    zjp
        11
    zjp  
       Jan 3, 2018
    @finull Java 泛型的实现里用了类型擦除,想要在运行时知道泛型的类型就得自己保存
    SoloCompany
        12
    SoloCompany  
       Jan 3, 2018
    因为类型擦除, 所有 concret type 的 Class<T> 中的 T 只能是 raw type
    数组也有类似的限制: new T[] 中的 T 也只能是 raw type
    如果你需要 parameterized type 的 class object 或数组, 只能靠 upcast

    比如
    List<String>[] list = new List[]; // new List<String>[] 是非法的
    Class<List<String>> classOfListOfString = List.class; // List<String>.class 当然也是非法的

    前者 (parameterized array) 有一定意义, 后者基本上毫无意义
    About     Help     Advertise     Blog     API     FAQ     Solana     3253 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 44ms UTC 12:02 PVG 20:02 LAX 05:02 JFK 08:02
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86