我有两个类,Foo和Bar,其类型声明如下:
class Foo<T>
class Bar<Foo>
这会导致编译器警告,因为Bar中的Foo参数没有被参数化。理想情况下,我想避免编译器警告,但是我希望Bar能够接受任何Foo。因此,我尝试了这个方法:
class Foo<T>
class Bar<Foo<?>>
这似乎很好用,但我担心可能有我忽略的微妙差别。有吗?
List<?> myList;
您不能向此列表中放入除 null 以外的任何内容。您也不能从此列表中获取除 Object
以外的任何内容。因此,编译器将不允许您通过添加不同类型的对象来破坏此列表的类型不变性。如果您尝试这样做,将会得到编译时错误。
但是,如果考虑以下列表(一个原始类型) -
List myList;
那么您就可以在此处放置任何内容/获取任何内容。因此,使用者可以轻松地通过放置不同类型的对象来破坏这个列表,如果幸运的话,您只能在运行时从 ClassCastException
中发现这一点。
因此,对于您的情况,请使用以下方法 -
class Foo<T>
class Bar<Foo<?>>
如果可以的话,请避免使用第一种类型。
要获取更多信息,请查看《Effective Java》 -
Foo<?>
语义上等同于Foo<? extends Object>
:它是一个具有特定类型参数的Foo
,但是关于“something”的唯一已知信息是它是Object的某个子类(这并没有说太多,因为所有类都是Object的子类)。
Bar<Foo<?>>
将会是一个语法错误 - 或许你的意思是将一个 变量 声明为Bar<Foo<?>>
。 - Paul Bellora