lis*_*sak 26 java generics wildcard
我不明白未绑定的通配符泛型的用途是什么.带有上边界的绑定通配符泛型<? extends Animal>非常有意义,因为使用多态性我可以使用该类型或集合.但是具有任何类型的泛型有什么意义呢?它不会破坏仿制药的目的吗?编译器没有发现任何冲突,在类型擦除之后,就像没有使用泛型一样.
Joa*_*uer 27
当您的方法不关心实际类型时,未绑定类型可能很有用.
一个原始的例子是这样的:
public void printStuff(Iterable<?> stuff) {
for (Object item : stuff) {
System.out.println(item);
}
}
Run Code Online (Sandbox Code Playgroud)
既然PrintStream.println()可以处理所有引用类型(通过调用toString()),我们不关心它的实际内容Iterable是什么.
并且来电者可以通过a List<Number>或a Set<String>或a Collection<? extends MySpecificObject<SomeType>>.
另请注意,不使用泛型(使用原始类型调用)会产生完全不同的效果:它使编译器处理整个对象,就好像泛型根本不存在一样.换句话说:不仅忽略类的类型参数,还忽略方法上的所有泛型类型参数.
另一个重要的区别是您不能null向a 添加任何(非)值Collection<?>,但可以将所有对象添加到原始类型Collection:
这将无法编译,因为类型参数c是未知类型(=通配符?),因此我们无法提供保证可分配给它的值(除了null可分配给所有引用类型的值).
Collection<?> c = new ArrayList<String>();
c.add("foo"); // compilation error
Run Code Online (Sandbox Code Playgroud)
如果将类型参数保留(即使用原始类型),则可以向集合中添加任何内容:
Collection c = new ArrayList<String>();
c.add("foo");
c.add(new Integer(300));
c.add(new Object());
Run Code Online (Sandbox Code Playgroud)
请注意,编译器将警告您不要使用原始类型,特别是出于这个原因:它删除与泛型相关的任何类型检查.
当您需要执行instanceof检查时.
你不能像这样参数化:
Object value;
if (value instanceof List<String>) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
所以你也是:
Object value;
if (value instanceof List<?>) {
// ...
}
Run Code Online (Sandbox Code Playgroud)