我有一个抽象类 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;
    }
}
最后通过强转能够解决
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;
    }
}
|  |      1gadfly3173      2021-12-24 11:48:44 +08:00  1 首先 string 没法被继承。。。这是 final class 。 保留 extends String 的话可以改成 ArrayList<T> strings = new ArrayList<>(); strings.add((T) "I'm Tiger"); | 
|      2Leviathann      2021-12-24 11:52:48 +08:00 翻译成 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 不能直接赋值给子类型 | 
|  |      3wolfie      2021-12-24 11:53:06 +08:00 编译期的东西不指定泛型就行。 或者 public abstract class Tiger extends Animal<String> { @Override public List<String> getList() {} } | 
|  |      4debuggerx      2021-12-24 11:54:21 +08:00 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; ----} } | 
|      5aguesuka      2021-12-24 11:55:32 +08:00 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; | 
|  |      6shily      2021-12-24 12:05:11 +08:00 所以楼主不看错误提示吗?问问题也不发错误提示吗? 楼上也就 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> | 
|  |      7unco020511      2021-12-24 17:38:38 +08:00 你需要一篮子苹果,我说我给你一篮子水果(水果里啥都有,除了苹果还有别的),你会同意吗? | 
|      8CodeGou      2021-12-24 22:14:35 +08:00 via Android kotlin 里有 in out 的概念。 |