关于Java中泛型的另一个非常基本的问题,直接来自previous question of mine。我们不是通过编写下面的代码两次向编译器提供相同的信息。为什么我们需要在左侧和右侧都提供这两者?为什么我们需要提供两次通用信息?
List<Number> numbers = new ArrayList<Number>();
编辑:当我在它,它不需要任何更多的Java 7中起了一些答案看看。但我想知道java 7之前不可能的原因是什么?
关于Java中泛型的另一个非常基本的问题,直接来自previous question of mine。我们不是通过编写下面的代码两次向编译器提供相同的信息。为什么我们需要在左侧和右侧都提供这两者?为什么我们需要提供两次通用信息?
List<Number> numbers = new ArrayList<Number>();
编辑:当我在它,它不需要任何更多的Java 7中起了一些答案看看。但我想知道java 7之前不可能的原因是什么?
因为pre java 7不支持构造函数的泛型类型推断。这在钻石运营商的java 7中得到了解决。
你也可以写通用的工厂方法作为一种解决方法,如:
public static <T> List<T> createArrayList() {
return new ArrayList<T>();
}
然后
List<Integer> list = createArrayList();
这是值得商榷的,但工程。也许为地图和其他多重论证的泛型类型带来好处。
到编辑:也许是语言的设计者决定不支持泛型类型推断,因为他们实现与类型擦除泛型。另一个可疑的决定,我认为...否则,不要认为在早期的Java版本中有任何反对这个特性的严重原因。 (并且通过Peter Lawrey的附录,它仍然不存在。)
正在引入钻石操作员来移除这些冗余信息。
看到这个链接SO以及What is the point of the diamond operator in Java 7?
从我读/理解我不认为泛型是做到了在Java中。这个?最后介绍的操作员是一件很痛苦的工作。有删除的事实表明,在我看来,它是鞋子。它可以完成这项工作,但我认为它可能会更好
请参阅编辑。我想了解java 7之前的问题是什么,这迫使设计人员以这种方式进行设计。 – Geek
因为一个是参考,一个是实现。该行的左侧设置了存储实例化变量的引用。由于Java使用“运行时类型擦除”来实现泛型,因此除了引用赋值之外的任何代码都无法知道Generic参数是什么分配。
编辑 - 我不知道J7的变化(我有点过时:)) - 看起来他们解决了这个问题。
除了其他答案中所述的原因外,本示例中右侧的参数不需要与左侧的参数完全相同。例如:
List<? extends Calendar> cals = new ArrayList<GregorianCalendar>();
从技术上讲''''不会进行类型推断,它只是不检查如果你编写'List numbers = new ArrayList <>();'它确定但是'列表 numbers = new ArrayList <>(){};'不是因为它需要知道创建类的实际类型。 –
@PeterLawrey:谢谢你的补充。 – zeller