代码之家  ›  专栏  ›  技术社区  ›  GhostCat

“var”和原始类型是如何组合在一起的?

  •  19
  • GhostCat  · 技术社区  · 7 年前

    我遇到一个 answer 建议使用

    var list = new ArrayList();
    

    我很惊讶在这里发现了一种原始类型,我只是想知道:是吗 var 使用 <> “自动?

    (同时,答案改为 <String> ,但我仍然对这里的“原则”感到好奇)

    我看到其他问题,比如 this ,但它们都使用菱形运算符:

    var list = new ArrayList<>();
    

    现在我只想知道:是不是 风险价值 改变我们应该(不)使用原始类型的方式?或者是不考虑 <> 仅仅是坏习惯?

    2 回复  |  直到 7 年前
        1
  •  31
  •   T.J. Crowder    7 年前

    我找到了一个建议用。。。

    我会忽略这个答案 ,因为正如您所指出的,它使用原始类型 it类型 list 具体来说 ArrayList . (更新:回答者编辑 their answer 添加元素类型。) 相反:

    List<AppropriateElementType> list = new ArrayList<>();
    

    根据 second answer you linked , var 如果包含 <> ,选择它能选择的最具体的类型。在 var list = new ArrayList<>(); 那就是 ArrayList<Object> 不过,因为它没有任何更具体的选择。

    但是 ,这个:

    var list = new ArrayList();
    

    ……没有 <> ,正在使用原始类型( 阵列列表 ),不是参数化类型 Object 作为参数( 数组列表<对象> ),这是不同的。


    如果使用 列表 足够包含(方法中的几行),并将其键入 ArrayList<X> 而不是 List<X> 可能可以接受(取决于您的编码风格),在这种情况下:

    var list = new ArrayList<AppropriateElementType>();
    

    但一般来说,我更喜欢使用接口而不是具体的类来编写代码,即使是使用局部变量。也就是说,对于当地人来说 不如实例成员重要,并且 风险价值 很方便。

        2
  •  10
  •   Oleksandr Pyrohov Andreas    7 年前

    两者兼用是合法的 var diamond ,但推断的类型将更改:

    var list = new ArrayList<>(); // DANGEROUS: infers as ArrayList<Object>
    

    对于它的推论, 钻石 可以使用目标类型(通常是声明的左侧)或构造函数参数的类型。如果两者都不存在,则返回到最广泛的适用类型,这通常是 Object .

    两者都有 钻石 和泛型方法,实际参数可以向构造函数或方法提供额外的类型信息,从而可以推断预期的类型 :

    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
    

    结论:

    1. 不使用原始类型,无论是否存在 风险价值 .
    2. 确保方法或构造函数参数提供足够的类型信息,以便推断的类型与您的意图匹配。否则,请避免同时使用 风险价值 具有 钻石 .

    1个- Style Guidelines 对于局部变量类型推断:G6。在钻石或一般方法中使用var时要小心。

    推荐文章