java - 变量已在方法 lambda 中定义

标签 java lambda java-8

考虑以下几乎可编译的 Java 8 代码:

public static void main(String[] args) {

    LinkedList<User> users = null;
    users.add(new User(1, "User1"));
    users.add(new User(2, "User2"));
    users.add(new User(3, "User3"));

    User user = users.stream().filter((user) -> user.getId() == 1).findAny().get();
}

static class User {

    int id;
    String username;

    public User() {
    }

    public User(int id, String username) {
        this.id = id;
        this.username = username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public int getId() {
        return id;
    }
}

你会注意到 User user = users.stream().filter((user) -> user.getId() == 1).findAny().get(); 抛出一个编译器错误:

variable user is already defined in method main(String[])

我的问题是:为什么 Lambda 表达式将 正在初始化 的变量与已定义的 Lambda 表达式放在同一行?我了解 Lambda 会在自身外部寻找(并使用)局部变量,因此您不能将在 Lambda 内部使用的变量命名为与外部变量相同的名称。但为什么正在定义的变量被认为已经定义了?

最佳答案

让我们转到 names and their scopes 上的 Java 语言规范

The scope of a formal parameter of a method (§8.4.1), constructor (§8.8.1), or lambda expression (§15.27) is the entire body of the method, constructor, or lambda expression.

The scope of a local variable declaration in a block (§14.4) is the rest of the block in which the declaration appears, starting with its own initializer and including any further declarators to the right in the local variable declaration statement.

然后,关于shadowing and obscuring的主题

A local variable (§14.4), formal parameter (§8.4.1, §15.27.1), exception parameter (§14.20), and local class (§14.3) can only be referred to using a simple name, not a qualified name (§6.2).

Some declarations are not permitted within the scope of a local variable, formal parameter, exception parameter, or local class declaration because it would be impossible to distinguish between the declared entities using only simple names.

It is a compile-time error if the name of a local variable v is used to declare a new variable within the scope of v, unless the new variable is declared within a class whose declaration is within the scope of v.

所以,在

User user = users.stream().filter((user) -> user.getId() == 1).findAny().get();

,变量 user 的范围是该 block 中它之后的所有内容。现在您正尝试使用该变量的名称在范围内声明一个新变量,但不是

within a class whose declaration is within the scope of v.

所以出现编译时错误。 (它是在 lambda 表达式中声明的,而不是在类中。)

关于java - 变量已在方法 lambda 中定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24642687/

相关文章:

java - while 循环 - 偶数之和及其平均值

java - 如何将openshift中的POD日志获取到本地文件

haskell - 不同 lambda 函数和字符的含义

java - 方法引用转换如何工作?

java - Android Java Http 请求发布

c# - 对具有多个级别的 Dictionary<string,Object> 进行排序

c++ - 如何给 lambda 一个持续时间与 lambda 一样长的内部值?

java - 在 Java 8 中设置装饰 JFrame 的不透明度

java - 为什么 Java 8 Optional 实现为 final,没有 Some 和 None 层次结构?

Java泛型如何避免接口(interface)不能用不同的参数实现多次