"array initializer needs an explicit target-type" - 为什么?

"array initializer needs an explicit target-type" - why?

正在关注 JEP 286: Local-Variable Type Inference 描述

我想知道,为什么要引入这样的限制,如:

Main.java:199: error: cannot infer type for local variable k

    var k = { 1 , 2 };
        ^   
(array initializer needs an explicit target-type)

所以对我来说逻辑上应该是:

var k = {1, 2}; // Infers int[]
var l = {1, 2L, 3}; // Infers long[]

因为Java编译器可以已经正确推断出数组的类型:

void decide() {
    arr(1, 2, 3);  // call  void arr(int ...arr)
    arr(1, 2L, 3); // call  void arr(long ...arr)
}

void arr(int ...arr) {
}

void arr(long ...arr) {
}

那么障碍是什么?

来自邮件列表 platform-jep-discuss,来自 Brian Goetz 的消息 Reader Mail Bag for Thursday (Thu Mar 10 15:07:54 UTC 2016)

  1. Why is it not possible to use var when the initializer is an array initializer, as in:

    var ints = { 1, 2, 3 }
    

The rule is: we derive the type of the variable by treating the initializer as a standalone expression, and deriving its type. However, array initializers, like lambdas and method refs, are poly expressions -- they need a target type in order to compute their type. So they are rejected.

Could we make this work? We probably could. But it would add a lot of complexity to the feature, for the benefit of a mostly corner case. We'd like for this to be a simple feature.

short-hand 数组初始值设定项从声明中获取其类型信息,但由于此处的声明是 var,因此必须明确指定。

您需要选择:

var k = new int[]{ 1 , 2 };

int[] k = { 1 , 2 };

允许var k = { 1 , 2 }会改变已经是语法糖的东西的语义。在 int[] n = { 1, 2 } 的情况下,类型由声明确定。如果你允许 var n = { 1, 2 } 类型突然由初始化程序本身决定。这可能会导致(更容易创建)编译器错误或歧义。

每次我们在 Java 中提高类型推断的范围时,我们都会得到一连串的 "but you could also infer this too, why don't you?"(或者有时,不太礼貌。)

关于设计类型推理方案的一些一般观察:

  • 推理方案总是有局限性的;总有一些情况处于边缘,我们无法推断出答案,或者最终推断出一些令人惊讶的事情。我们越努力去推断一切,我们就越有可能推断出令人惊讶的事情。这并不总是最好的权衡。
  • cherry-pick "but surely you can infer in this case." 的例子很容易,但如果这些案例与其他没有明显答案的案例非常相似,我们只是把问题转移了 -- "why does it work for X but not Y where X and Y are both Z?"
  • 总是可以制定推理方案来处理增量案例,但几乎总是存在附带损害,要么是在其他情况下得到更糟糕的结果,要么是增加不稳定性(看似无关的变化可能会改变推断的类型) ), 或更复杂。您不想仅针对可以推断的案例数量进行优化;您还想优化受过教育的用户预测什么有效什么无效的能力。绘制更简单的线条(例如,不要费心去尝试推断数组初始值设定项的类型)通常在这里是一个胜利。
  • 鉴于总是有限制,通常最好选择一个较小但 better-defined 的目标,因为这样可以简化用户模型。 (参见 "why can't I use type inference for the return type of private methods. The answer is we could have done this, but the result would be a more complicated user model for small expressive benefit. We call this " 差 return-on-complexity 的相关问题。”)