1.无界通配速
无界通配符 Set<?>可以容纳任何类型的元素,而原始类型Set也可以容纳任何类型的元素。那它们之间有什么区别呢?
关于Set<?>有两个事实:
Item 1:?代表任何类型。Set<?> 可以容纳任何类型的元素。
Item 2:因为我们不知道?的类型,所以不能将任何元素放入Set<?>。
由于 Set<?> 可以容纳任何类型的元素,因此我们仅在循环中使用Object。
因为我们不完全知道 <?> 的类型,所以除了null之外,我们无法添加其他任何内容。出于相同的原因,我们无法使用 Set<?> 初始化集合。
因为原始类型没有限制。但是,这很容易破坏集合的不变性。
简而言之,通配符类型是安全的,而原始类型则不是。我们不能将任何元素放入Set<?>中。
如果要使用泛型类型,但不知道或不在乎该参数的实际类型,则可以使用<?> 。它只能使用方法的参数。
2.列表与数组

数组是协变的(covariant)(若Sub是Super的子类型,Sub[]也是Super[]的子类型),是不安全的。
3.有限制的通配符
为了获得最大限度的灵活性,要在表示生产者或者消费者的输入参数上使用通配符类型。如果某个输入参数既是生产者,也是消费者,那么通配符就没有什么好处了:因为需要的是严格的类型匹配。
需要注意的是JVM规范对参数化的类型也做了相应的修改,引入了Signature的重要属性,所谓的类型擦除只是Code属性中的字节码进行了擦除,实际上元数据中仍然保存了泛型信息,这是我们能通过反射手段获取参数化类型的根本依据。
参考:《effective java》
写的不好 大家直接看这篇吧:
https://www.cnblogs.com/en-heng/p/5041124.html
网友评论