请教大佬一个泛型的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
Macolor21
V2EX    Java

请教大佬一个泛型的问题

  •  
  •   Macolor21 Dec 24, 2021 2943 views
    This topic created in 1587 days ago, the information mentioned may be changed or developed.

    我有一个抽象类 Animal, 如下

    public abstract class Animal<T> { public List<T> getList(){ return new ArrayList<>(); } } 

    我想要扩展这个抽象类的功能,于是我继承了该抽象类实现了 Tiger 。在这里我会限制 Tiger 的泛型必须是 String 的子类。

    我的核心需求是扩展 getList 方法,让其返回值不再是空 List, 而是包含一个元素 "I'm Tiger" 的字符串集合。

    以下面的写法,IDEA 会编译出错,请问有什么其他方式实现这个需求吗?

    public abstract class Tiger<T extends String> extends Animal<T> { @Override public List<T> getList() { ArrayList<String> strings = new ArrayList<>(); strings.add("I'm Tiger"); return strings; } } 
    Supplement 1    Dec 24, 2021

    最后通过强转能够解决

    public abstract class Tiger<T extends String> extends Animal<T> { @Override public List<T> getList() { ArrayList<String> strings = new ArrayList<>(); strings.add("I'm Tiger"); return (List<T>) strings; } } 
    8 replies    2021-12-24 22:14:35 +08:00
    gadfly3173
        1
    gadfly3173  
       Dec 24, 2021   1
    首先 string 没法被继承。。。这是 final class 。
    保留 extends String 的话可以改成
    ArrayList<T> strings = new ArrayList<>();
    strings.add((T) "I'm Tiger");
    Leviathann
        2
    Leviathann  
       Dec 24, 2021
    翻译成 ts ,报错更友好
    ‘string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'String'.
    只能返回 T 的子类型而不是 string
    因为 string 不能直接赋值给子类型
    wolfie
        3
    wolfie  
       Dec 24, 2021
    编译期的东西不指定泛型就行。

    或者

    public abstract class Tiger extends Animal<String> {
    @Override
    public List<String> getList() {}
    }
    debuggerx
        4
    debuggerx  
       Dec 24, 2021
    Tiger.java:

    public abstract class Tiger extends Animal<String> {
    --@Override
    ----public List<String> getList() {
    ------ArrayList<String> strings = new ArrayList<>();
    ------strings.add("I'm Tiger");
    ------return strings;
    ----}
    }
    aguesuka
        5
    aguesuka  
       Dec 24, 2021
    String 是 final 的.
    如果 String 不是 final 的, 假如它有一个子类 A. 那么我可以定义 Tiger<A> tiger, 但是 tiger.getList().get(0) 会报 ClassCastException, 因为期待的类型是 A, 实际上是 String. 就像一楼那样
    实际上应该是

    ArrayList<T> strings = new ArrayList<>();
    strings.add(aObjectWhichClassIsT);
    return strings;
    shily
        6
    shily  
       Dec 24, 2021
    所以楼主不看错误提示吗?问问题也不发错误提示吗?

    楼上也就 2 楼靠谱。


    根本原因是父类的 List 无法直接赋值给子类 List; 比如 List<Object> 是无法赋值 给 List<String> 的,因为你无法判断 List 里是否有不合法的数据。

    例如:
    ArrayList<Object> objs = new ArrayList<>();
    objs.add("I am string");
    Integer iAmInteger = 10;
    objs.add(iAmInteger);


    // 一下的场景中 String 就是 T extends Object
    List<String> strings = objs; // 此处编译错误,提示需要 List<String> 但是提供了 List<Object>
    unco020511
        7
    unco020511  
       Dec 24, 2021
    你需要一篮子苹果,我说我给你一篮子水果(水果里啥都有,除了苹果还有别的),你会同意吗?
    CodeGou
        8
    CodeGou  
       Dec 24, 2021 via Android
    kotlin 里有 in out 的概念。
    About     Help     Advertise     Blog     API     FAQ     Solana     3119 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 50ms UTC 14:18 PVG 22:18 LAX 07:18 JFK 10:18
    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