generics无法实例化`new HashMap `。 为什么?
为什么以下代码行在HashMap中出错? 它并没有在任务的右侧使用外卡。
Map map=new HashMap();
您不能像这样实例化参数化类型。 通配符参数化类型不是具体类型,因此它们不能出现在新表达式中。
通配符参数化类型表示包括generics类型的具体实例的类型族。 正在使用的通配符类型决定了哪些具体参数化类型属于该族。
因此, Map
表示类型系列,可以是Map
, Map
,任何东西。 您必须在创建实际地图时使用具体类型。
所以,你可以这样做:
Map map=new HashMap(); Map map=new HashMap();
但是这个声明的问题在于,除了null
之外,你不能向map添加任何东西。
另一方面,考虑其他类型的通配符 – 上限和下限 。
上限有界通配符 :
Map
此类型表示的类型族是具体实例化,其中值类型是Number
或Number
的子类型。 因此,对于这一个,以下是具体参数化类型的有效创建:
Map map = new HashMap(); Map map = new HashMap();
但同样,这里的问题是你不能在地图中添加任何东西,除了null
或之前从中获取的值。
下限有界通配符 :
Map
如您所知,您无法使用无界通配符或上限通配符向通配符参数化类型添加任何内容。 还有第三种类型 – 下限有界通配符,如果要向地图添加内容,可以使用它。 上述参数化类型的类型系列是获取Integer
类型值或超类型的类型。 所以,你可以像这样实例化它:
Map map = new HashMap(); Map map = new HashMap(); Map map = new HashMap();
但这里还有另一个问题。 虽然您可以为其添加值,但是当您获取某些值时,您无法确定所获得的类型。
因此,根据您的要求,您可能必须使用一种或另一种类型的通配符。 可能是问题中的更多信息可能对您有所帮助。 但是,一般只记得,你不能创建一个通配符参数化类型的对象,而只能创建具体的参数化类型。
在实例化具体类的对象时,不能使用通配符。
做就是了:
class SuperBogusUnrelatedClass {} // ... Map map = new HashMap();
以上是正确的,100%类型安全。 说真的,你可以放任何东西,甚至是Math
。 为什么这是正确的? 因为它是一个通配符,它意味着它可以是任何东西; 你不知道它是什么。
上面例子的荒谬也说明了为什么这个初始化几乎完全没用 – 因为类型参数是未知的,你不能安全地将任何值(除了null
)放入Map
。 因此,您的Map
必须为空,或者填充值为null
条目。 所以基本上,它相当于一个Set
。
由于您要创建HashMap
对象,因此必须指定所有通用参数。
在Java 7及更高版本中,您可以使用此处提到的菱形表示法:
https://docs.oracle.com/javase/tutorial/java/generics/types.html#diamond
这是一个使用从问题中显示的代码行派生的钻石的快速示例:
Map map=new HashMap<>();
您正在实例化一个类型为类型参数的对象。这是不可能的。
因为编译器不知道如何创建未知类型的对象。
更多细节我可以创建一个类型为类型参数的对象吗?