我有两个类,Foo和Bar,带有类型声明:
class Foo<T>
class Bar<Foo>
这会导致编译器警告,因为Bar中的Foo参数没有参数化。理想情况下,我想避免编译器警告,但我确实希望Bar接受任何Foo。所以我尝试了这个:
class Foo<T>
class Bar<Foo<?>>
这似乎工作正常,但我担心可能会有一些我遗漏的细微差别。有吗?
答案 0 :(得分:5)
是的,有。考虑一下 -
List<?> myList;
除了null之外,您无法将任何内容放入此列表中。除了Object
之外,您也无法从此列表中获取任何内容。因此编译器不允许您通过允许添加不同类型的对象来破坏此列表的类型不变量。如果您尝试这样做,则会出现编译时错误。
但如果您考虑以下列表(原始类型) -
List myList;
那么你可以放任何东西/从这里得到任何东西。因此,人们可以通过放置不同类型的对象轻松破坏此列表,并且您只能在运行时从ClassCastException
找到相关信息(如果您很幸运......)。
因此,对于您的情况,请使用以下方法 -
class Foo<T>
class Bar<Foo<?>>
如果可以,请远离第一个。
有关详细信息,请查看Effective Java -
答案 1 :(得分:1)
Foo<?>
在语义上与Foo<? extends Object>
相同:它是Foo
,具有特定类型的类型参数,但唯一知道“某事”的是它是某个子类的对象(这并没有说太多,因为所有类都是Object的子类)。