下一行为什么不编译?

时间:2019-07-30 18:44:41

标签: java generics arraylist compiler-errors

我试图通过使用具有无限制通配符的泛型来创建一个可以包含任何类型对象的arraylist。

ArrayList<?> params = new ArrayList<?>(); 

我不明白为什么会收到以下错误,我想知道我要去哪里?

  required: class or interface without bounds
  found:    ?

3 个答案:

答案 0 :(得分:2)

您根本不允许这样做。它在JLS 15.9中这样说:

  

如果紧接在新变量之后或之前存在(TypeArguments),则任何类型参数都是通配符(§4.5.1)都将导致编译时错误。

列表 instance 永远不会有边界类型:列表始终是包含特定类型元素的列表。

只有列表变量可以有界,以便在列表中存储具有特定类型元素的列表。

所以,这很好:

ArrayList<?> params = new ArrayList<SomeType>(); 

ArrayList<?> params = new ArrayList<>();

这并不是说您完全不能在RHS上使用界限:

new ArrayList<List<?>>()

会很好,因为List<?>不是通配符(因为语法上的通配符总是以?开头)。

答案 1 :(得分:1)

解决问题的一种简单方法是使用ArrayList<Object>

ArrayList<Object> params = new ArrayList<>(); 

?运算符引用所有类型未知的对象,因此,如{{3}中所述,使用它添加已知类型的对象(例如字符串)将导致错误。 }。

答案 2 :(得分:1)

您不能写new ArrayList<?>,因为没有ArrayList<?>之类的东西。

每个ArrayList都具有特定类型。编写ArrayList<?> params时,您告诉编译器:“此变量将保存一个ArrayList,其元素是特定类型,例如String或Number。 ,但是在编写此行代码时,我不知道该类型是什么。”

因此,您可以引用,使其具有在编译时未知的类型,但是每个现有的ArrayList都具有实际类型,无论变量如何引用它。代码创建ArrayList时,必须指定该类型。