“var”和原始类型如何结合在一起?
Posted
技术标签:
【中文标题】“var”和原始类型如何结合在一起?【英文标题】:How do "var" and raw types come together? 【发布时间】:2019-01-13 07:42:24 【问题描述】:我遇到了一个建议使用的answer
var list = new ArrayList();
我很惊讶在这里发现了一个原始类型,我只是想知道:var
是否自动使用<>
“?
(同时答案改用<String>
,不过我还是好奇不过这里的“原理”)
看到this之类的其他问题,都用菱形运算符:
var list = new ArrayList<>();
现在我只是想知道:var
是否改变了我们应该(不)使用原始类型的方式?还是说忽略<>
的建议只是不好的做法?
【问题讨论】:
仅供参考,the answer 您在第一句话中链接的内容已被作者编辑添加为<String>
。
@SudhirOjha 你也有同样的问题:在那个问题中,any 讨论了关于将原始类型与 var 结合使用的讨论?
好问题。我想this article by Brian 和another one by Stuart 可能是更好地了解风格和风险的好书。 Holger 是pointing to the raw types as well,我猜,他看到了这样一个问题。
这很简单。对于 var
声明的本地变量,我们将 RHS 的类型计算为独立表达式(然后执行称为 upward projection 的过程来投影捕获变量。)如果 RHS 是原始的,则推断的类型是原始类型。没有魔法。
@SudhirOjha 我不认为这是我的问题的重复,因为我的问题根本不涉及原始类型。
【参考方案1】:
我遇到了一个建议使用的答案...
我会忽略这个答案,因为正如您所指出的,它使用原始类型并且它将list
类型具体为ArrayList
。 (更新:回答者编辑 their answer 以添加元素类型。) 改为:
List<AppropriateElementType> list = new ArrayList<>();
根据second answer you linked,如果您包含<>
,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 替换)到右侧键入信息。在我注意到有人对此发表评论并有机会修复它之前,有人问了这个问题。【参考方案2】:
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 - Style Guidelines 用于局部变量类型推断:G6。将 var 与菱形或泛型方法一起使用时要小心。
【讨论】:
以上是关于“var”和原始类型如何结合在一起?的主要内容,如果未能解决你的问题,请参考以下文章