我有一个抽象类 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;
}
}
1
gadfly3173 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"); |
2
Leviathann 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 不能直接赋值给子类型 |
3
wolfie 2021-12-24 11:53:06 +08:00
编译期的东西不指定泛型就行。
或者 public abstract class Tiger extends Animal<String> { @Override public List<String> getList() {} } |
4
debuggerx 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; ----} } |
5
aguesuka 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; |
6
shily 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> |
7
unco020511 2021-12-24 17:38:38 +08:00
你需要一篮子苹果,我说我给你一篮子水果(水果里啥都有,除了苹果还有别的),你会同意吗?
|
8
CodeGou 2021-12-24 22:14:35 +08:00 via Android
kotlin 里有 in out 的概念。
|