之间有区别吗
<N extends Number> Collection<N> getThatCollection(Class<N> type)
and
Collection<? extends Number> getThatCollection(Class<? extends Number>)
它们公开了不同的接口和方法契约。
第一个声明应返回一个集合,其元素类型与参数类相同。编译器推断类型N
(如果未指定)。因此,当使用第一个声明时,以下两个语句是有效的:
Collection<Integer> c1 = getThatCollection(Integer.class);
Collection<Double> c2 = getThatCollection(Double.class);
第二个声明没有声明返回的 Collection 类型参数与参数类之间的关系。编译器假设它们不相关,因此客户端必须将返回的类型用作Collection<? extends Number>
,无论参数是什么:
// Invalid statements
Collection<Integer> c1 = getThatCollection(Integer.class); // invalid
Collection<Double> c2 = getThatCollection(Double.class); // invalid
Collection<Number> cN = getThatCollection(Number.class); // invalid
// Valid statements
Collection<? extends Number> c3 = getThatCollection(Integer.class); // valid
Collection<? extends Number> c4 = getThatCollection(Double.class); // valid
Collection<? extends Number> cNC = getThatCollection(Number.class); // valid
推荐
如果返回的类型参数和传递的参数之间确实存在类型关系,则最好使用第一个声明。如上所述,客户端代码更加清晰。
如果这种关系不存在,那么最好避免第二次声明。具有有界通配符的返回类型迫使客户端在任何地方使用通配符,因此客户端代码变得混乱且不可读。约书亚·布洛赫 (Joshua Bloch) 强调你应该避免返回类型中使用有界通配符(幻灯片 23)。虽然返回类型中的有界通配符在某些情况下可能很有用,但恕我直言,结果代码的丑陋应该会覆盖它的好处。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)