Consider the following almost compilable Java 8 code:
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;
}
}
You'll notice User user = users.stream().filter((user) -> user.getId() == 1).findAny().get();
throws a compiler error:
variable user is already defined in method main(String[])
My question is: Why do Lambda expressions consider the variable that is being initialized on the same line as the Lambda expression as already defined? I understand Lambdas look outside themselves for (and use) local variables, so you can't name the variables you use inside the Lambda the same as an outside variable. But why is the variable that is being defined considered already defined?
user
is defined beforeuser
is in the lambda expression. – Parameteruser
argument is actually expected to be used within a totally different context (the evaluation context of the expression), and so why should it be affected by theuser
variable defined outside? – Kissneruser
is part of the closure environment, it is already within the context of the lambda expression, and so, if you declare another variableuser
, there is a name conflict. However, I still wonder, why was it not simply shadowed. Can this be related to how things are instrumented under the hood? – Kissneruser
is declared though not yet initialized. This is the same for local variables without lambdas, e.g. forint x=x+1;
the secondx
will refer to the variablex
which is already declared but the reference is invalid asx
is not initialized at that point. There will be no attempt to find an initializedx
in an outer scope. – Qualls