0
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
}

0 Answers0