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

为什么Java不支持构造函数的类型推断?

  •  7
  • Tarski  · 技术社区  · 16 年前

    例如,要创建字符串的ArrayList,我们必须执行以下操作

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

    然而,它应该能够推断构造函数的参数类型,这样我们只需要

    List<String> list = new ArrayList();
    

    为什么不能像为泛型方法推断类型参数那样推断类型。

    7 回复  |  直到 15 年前
        1
  •  22
  •   Bill the Lizard    14 年前

    这是Java7的改进,也称为菱形操作符。语法将是:

    List<String> strings = new ArrayList<>();
    

    官方建议,, accepted for inclusion in Project Coin Improved Type Inference for Generic Instance Creation

    Rémi Forax ,更改已在mercurial存储库中。

        2
  •  6
  •   Jon Skeet    16 年前

    正如其他人所说,这是一个错误 on the list for Java 7 Google Collections Library 如果您愿意使用静态导入的话,已经对各种集合提供了某种程度的支持。例如,我经常编写以下代码:

    List<String> list = newArrayList();
    

    new ArrayList() :)

    (静态导入将是到 Lists 类,顺便说一句。地图等也有类似的方法。)

        3
  •  2
  •   Allain Lalonde    16 年前

    它可以是,而且它是一个预定包含在 JDK7 .

        4
  •  2
  •   Shizzmo    16 年前

    除了JDK7特性之外,我猜您可以使用 延伸 超级的

    class Animal {}
    class  Dog extends Animal {}
    
    List<? extends Animal> anims = new ArrayList<Dog>();
    List<? super Dog> superdogs = new ArrayList<Animal>();
    

    在这两种情况下你无法推断。

        5
  •  2
  •   Bill K    16 年前

    您想知道当前Java不支持它的原因。

    我只能说,Java通常在可能的情况下只需要很少的步骤。我猜在Java 7出现之前,有一些小的技术故障,他们不确定是否“正确”,这可能与绝对确定它不会在一些旧的或非泛型代码中产生歧义有关。

    List<String> strings = new ArrayList<>();
    

    注意空的<>?我猜这是为了从较旧的非泛型代码中消除这种推理的歧义;这可能是他们一开始没想到的。

        6
  •  1
  •   Marko    16 年前

    类型是可以推断的,但作者只是决定,在某些情况下,最好根本不进行类型推断,然后再进行一些有限的类型推断。

    如果您想在jvm上进行类型推断,请查看 scala .

        7
  •  0
  •   Philippe    16 年前

    我不是Java超级专家,所以我不能完全确定我将陈述什么。以下是我的想法:

    由于Java通过擦除实现泛型,所以对于每个泛型类型,都有一个底层的原始类型。如果定义泛型类型,则将有一个将使用 Object 到处都是。

    当您实例化一个新的 ArrayList ,编译器从实例化类推断类型参数是错误的( ArrayList<String> ArrayList <>

    new ArrayList() 陈述

    我希望这是清楚的,如果我错了,有人可以纠正我。


    另外,请注意原始类与使用 作为类型参数:

    List<String> list = new ArrayList();
    

    有效,其中为

    List<String> list = new ArrayList<Object>();
    

    事实并非如此。在第一种情况下,可以像使用泛型类型一样使用原始类型,但在第二种情况下,您要求使用不可用的逆变(如果不使用通配符,则不可用)。