首先观察:
Holder h = new Holder<>(new B());
用Java 8和Java 7编译,并且都创建Holder< B>在那种情况下.所以使用<>使用带参数的构造函数很好.
然而:
Holder h = new Holder<>(new B());
> Java 7首先评估右侧,确定它是Holder< B>.并给出编译错误,因为a Holder can’t be converted into a Holder.
> Java 8更进了一步,推断出新的Holder< A>(新的B())实际上可以工作并自动神奇地完成.这要归功于一项名为“目标打字”的新功能 – 请参阅the tutorial on type inference的最后一部分以获取概述.
更详细地说,Java 8的改进是由于引入了poly expressions(强调我的):
The type of a standalone expression can be determined entirely from the contents of the expression; in contrast,the type of a poly expression may be influenced by the expression’s target type (§5 (Conversions and Contexts)).
这是Java 8的一个非常强大的功能(Java 7仅提供不考虑表达式上下文的独立表达式).
泛型类实例创建是一个多义表达式,JLS #15.9解释(强调我的):
A class instance creation expression is a poly expression (§15.2) if it uses the diamond form for type arguments to the class,and it appears in an assignment context or an invocation context (§5.2,§5.3). Otherwise,it is a standalone expression.
由于新的规则,Java 8允许您使用上面的第二种形式,并自动推断新的B()应该被视为A(加宽参考转换),并且您打算创建一个Holder< A>.在这种情况下.