Java,Generics:Set <?> s = HashSet()和Set s = HashSet()之间有什么区别?

参见英文答案 > Difference between List, List<?>, List<T>, List<E>, and List<Object>                                    10个
我正在阅读有关仿制药中未知类型和原始类型的内容,我想到了这个问题.换句话说,是……

Set<?> s = new HashSet<String>();

Set s = new HashSet<String>();

……一个一样?

我试了一下,他们似乎都完成了同样的事情,但我想知道他们是否与编译器有任何不同.

最佳答案
不,他们不一样.这是基本的区别:

Set<?> s = HashSet<String>();
s.add(2);  // This is invalid

Set s = HashSet<String>();
s.add(2);  // This is valid.

关键是,第一个是无界参数化类型Set.编译器将在那里执行检查,并且由于您不能向这些类型添加除null之外的任何内容,编译器将给您一个错误.

虽然第二个是原始类型,但编译器在向其添加任何内容时不会进行任何检查.基本上,你在这里失去了类型安全.

你可以看到那里失去类型安全的结果.在Set<?>的编译时,为集合添加2将失败,但对于原始类型Set,它将成功添加,但是当您从集合中获取元素并分配它时,它可能会在运行时抛出异常说String.

除此之外,您应该避免在较新的代码中使用原始类型.您很少会找到任何可以使用它的地方.使用原始类型的几个地方是访问该类型的静态字段,或获取该类型的Class对象 – 您可以执行Set.class,但不能设置<?> .class.

转载注明原文:Java,Generics:Set <?> s = HashSet()和Set s = HashSet()之间有什么区别? - 代码日志