Let’s consider the following Java program:
import java.util.*;
import java.util.stream.Collectors;
public class Main {
record Foo(String id, List<Bar> bars) {}
record Bar(String id) {}
public static void main(String[] args) {
Map<String, Map<String, Bar>> barsByFooIdAndBarId = Collections.<Foo>emptyList()
.stream()
.collect(
Collectors.toMap(
Foo::id,
foo ->
Collections.<String, Bar>emptyMap()
.entrySet()
.stream()
.collect(
Collectors.toMap(
Map.Entry::getKey,
entry ->
foo
.bars()
.get(0)
)
)
)
);
Bar bar = barsByFooIdAndBarId
.computeIfAbsent("fooId", id -> Collections.emptyMap())
.get("barId");
System.out.println(bar);
}
}
What it does is totally irrelevant to us, we’re only interested by types here. If you change barsByFooIdAndBarId
‘s type from Map<String, Map<String, Bar>>
to var
, you should leverage Java type inference and get exactly the same program.
While this works fine with javac and IntelliJ, this fails miserably with the VS Code extension “Language Support for Java(TM) by Red Hat”. The inferred type is Map<String, Map<String, Object>>
in that case. As a result, the assignment to Bar bar
does not typecheck as Object
is not assignable to Bar
.
I know that this Java extension is based on Eclipse’s Java language server but I haven’t been able to interact with the language server directly yet. This issue may come from the language server but I’m not entirely sure. Any ideas?