Java 8:目标输入


问题内容

在阅读 Lambda的状态一文时, 我遇到了 目标打字 这一主题,我对以下段落感到有些困惑:

ActionListener l = (ActionEvent e) -> ui.dazzle(e.getModifiers());

这种方法的含义是,相同的lambda表达式在不同的上下文中可以具有不同的类型:

Callable<String> c = () -> "done";

PrivilegedAction<String> a = () -> "done";

在第一种情况下,lambda表达式() -> "done"表示的实例Callable。在第二种情况下,相同的表达式表示PrivilegedAction的实例。

编译器负责推断每个lambda表达式的类型。它使用表达式出现的上下文中期望的类型。这种类型称为目标类型。Lambda表达式只能出现在目标类型为功能接口的上下文中。

您能否以简单的方式向我解释与引用的段落有关的这些要点:

  1. 目标类型
  2. 语境

如果您还提供代码段,我将非常感谢。


问题答案:

语境

上下文 是在代码中使用表达式的方式。这不只是lambda表达式-这是任何表情,像a+ba++Math.random()

可能的情况示例:

  • 作业: 取表达式a+b。如果将其分配给变量,则会在分配上下文中使用它:

    c = a+b;
    
  • 方法或构造函数的参数: 。这是当您将其传递给某些方法调用时:

    System.out.println(a+b);
    
  • 返回值:return语句中使用表达式时:

    return a+b;
    
  • 数组索引: 当您的表达式是数组索引时:

    x[a+b] = 3;
    

目标类型

目标类型 是预期在给定上下文的类型。例如,如果您将方法定义为:

public int myMethod() { ... }

那么return语句主体中的任何表达式都应该具有类型int。因此,如果您有:

return a+b;

在内部myMethod,预计a+b将解析为int或可分配给int的内容。

现在,假设您具有以下方法:

public void anotherMethod( double d );

然后,当您调用它并传递一个表达式作为参数时,该表达式应为type double。像这样的电话:

anotherMethod(a+b);

希望a+b解决一个double。那是它的 目标类型

在你的例子中

在声明中:

Callable<String> c = () -> "done";

该表达式是lambda表达式() -> "done"。在 分配 环境中使用它(分配给c)。而 目标类型
Callable<String>因为这是您向分配任何内容时所期望的c


有关更正式的讨论,请参阅Java语言规范的第5章