为什么不允许使用以下代码?
class MyClass {
List<? extends Something> list;
<T extends Something> List<T> myFunc(T t) {
list = new ArrayList<T>(); // ok
list.add(t); // error
return list; // error
}
}
如何在保持相同的同时修复代码?即类成员list
仅接受Something
的子类和myFunc()
的子类相同的对象?
答案 0 :(得分:2)
我认为Generic <T>
声明可以在课程级别完成。
据我所知,这是因为通配符?
不能用作类型参数。
通配符永远不会用作泛型方法调用,泛型类实例创建或超类型的类型参数
所以我得到的是Java不会知道<T extends Something>
以及即使它具有扩展相同的上下文的列表,也不能确保它是相同类型的。
一个可能的(可能不是你想要的)解决方案将在类级别声明Generic。
如果我们这样做可能会有效:
class Abc <T extends Something>{
List<T> list;
List<T> myFunc(T t) {
list = new ArrayList<T>(); // ok
list.add(t);
return list;
}
}
我希望它有所帮助。
答案 1 :(得分:0)
在任何地方使用之前,您必须在某处定义T
类型参数。理想情况下,您应该使用类声明来定义它。因为你已经在课堂上的很多地方使用过它。如果T
仅用于方法范围,则可以使用方法签名定义它。
您无法修改上限 <T extends Something>
和无界 <?>
类型实例。
这意味着,不允许向List<?>
(无界列表)和List<T extends Something>
添加任何元素。
如果要使其正常工作,可以使用List的下限类型参数。
class MyClass<T super Something> {
List<T super Something> list;
<T super Something> List<T> myFunc(T t) {
list = new ArrayList<T>(); // ok
list.add(t);
return list;
}
}
答案 2 :(得分:0)
您无法list.add(t);
,因为list
的类型为List<? extends Something>
而t
的类型为T
,并且无法知道T
是否?
1}}是return list;
代表的未知类型的子类型。
同样,您无法执行list
,因为List<? extends Something>
的类型为List<T>
,列表的返回类型为List<? extends Something>
,无法知道{是否{ {1}}是List<T>
。
我认为您的想法是将List<T>
放入变量中,因此您知道它是List<T>
,并且您尝试将其用作List<T>
。但这不是它的工作原理。 list
的类型为List<? extends Something>
。无论你输入什么,都不会改变变量的类型,变量的任何使用仍然必须基于它的编译时类型。
如果你想在后面的方法中使用你为List<T>
创建的对象,你需要保留一个List<T>
类型的变量来指向它,如下所示:< / p>
<T extends Something> List<T> myFunc(T t) {
List<T> tempList = new ArrayList<T>();
list = tempList;
tempList.add(t);
return tempList;
}