List<AppropriateElementType> list = new ArrayList<>();
<>
,var
将会导致编译器从右侧推断出元素类型,并选择最具体的类型。在var list = new ArrayList<>();
中,这将是ArrayList<Object>
,因为它没有更具体的类型可选。var list = new ArrayList();
...没有使用<>
,而是使用了原始类型(ArrayList
),没有使用参数化类型,参数应该是Object
(ArrayList<Object>
),这是不同的。
如果使用list
的范围足够小(在一个方法中只有几行),那么将其类型定义为ArrayList<X>
而不是List<X>
可能是可以接受的(取决于您的编码风格),在这种情况下:
var list = new ArrayList<AppropriateElementType>();
但通常我更喜欢编写针对接口而不是具体类的代码,即使是在局部变量中也是如此。话虽如此,在局部变量中,这比实例成员更不重要,而var
很方便。
var
表达式看起来的方式,并且我忘记将类型信息从左侧移动到右侧(被var
替换了)。在我注意到这一点并有机会修复之前,这个问题就被提出了。 - Thorbjørn Ravn Andersen使用var
和diamond
都是合法的,但是推断出的类型会发生变化:
var list = new ArrayList<>(); // DANGEROUS: infers as ArrayList<Object>
为了进行推断,diamond
可以使用目标类型(通常是声明的左侧)或构造函数参数的类型。如果两者都不存在,则回退到最适用的最广泛类型,通常是Object
1。
通过diamond
和泛型方法,可以通过构造函数或方法的实际参数提供额外的类型信息,从而允许推断所需的类型1:
var list = List.of(BigInteger.ZERO); // OK: infers as List<BigInteger>
var list = new ArrayList<String>( ); // OK: infers as ArrayList<String>
鉴于上述情况,我不建议执行以下操作(因为您将获得原始的 ArrayList
类型):
var list = new ArrayList(); // DANGEROUS: infers as ArrayList
var
,都不要使用原始类型。var
和diamond
1。1 - 本地变量类型推断的风格指南: G6. 在使用带有菱形语法(diamond)或泛型方法时要小心使用var。
<String>
。 - T.J. Crowdervar
声明的局部变量,我们将 RHS 的类型作为独立表达式进行计算(然后执行一种称为“向上投影”的过程来消除捕获变量)。如果 RHS 是原始类型,则推断出的类型也是原始类型。没有任何魔法。 - Brian Goetz