static class Foo {
public Map<String, String> myMap() {
return new HashMap<>();
}
}
static class Bar<A> {
public Map<String, String> myMap() {
return new HashMap<>();
}
}
static {
Foo foo = new Foo();
foo.myMap().get("Test").charAt(0); // compiles just fine
Bar bar = new Bar();
bar.myMap().get("Test").charAt(0); // can not resolve method "charAt"
}
So, this is pretty weird. Java appears to be forgetting the generic type of the Map when I go to use it (it does not give me access to String's methods AT COMPILE TIME without explicit casting). But this only happens when the map was returned from a method in another generic class, even though the generics for that class are not even used. Very annoying. Happens to other collections and methods, including iterators.
I should also note that the following does compile, despite being functionally identical to our earlier usage of Bar, right?
Map<String, String> map = bar.myMap();
map.get("Test").charAt(0);
Is this a compiler bug that needs to be reported, or just some quirk of Java that I do not understand?
Edit: There is also this...
static class Weird extends Bar<Object> {
}
static {
Bar bar = new Weird<>();
bar.myMap().get("Test").charAt(0); // Can not resolve method "charAt"
Bar<?> betterbar = new Weird();
betterbar.myMap().get("Test").charAt(0); // compiles fine
Weird weird = new Weird();
weird.myMap().get("Test").charAt(0); // compiles fine
}