Java loosing generics for a collection at compile time. Not type erasure, compiler bug?
<pre><code>static class Foo {
    public Map&lt;String, String&gt; myMap() {
        return new HashMap&lt;&gt;();
    }
}

static class Bar&lt;A&gt; {
    public Map&lt;String, String&gt; myMap() {
        return new HashMap&lt;&gt;();
    }
}

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"
}
</code></pre>

<p>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.</p>

<p>I should also note that the following does compile, despite being functionally identical to our earlier usage of Bar, right?</p>

<pre><code>Map&lt;String, String&gt; map = bar.myMap();
map.get("Test").charAt(0);
</code></pre>

<p>Is this a compiler bug that needs to be reported, or just some quirk of Java that I do not understand?</p>

<p>Edit:
There is also this...</p>

<pre><code>static class Weird extends Bar&lt;Object&gt; {
}

static {
    Bar bar = new Weird&lt;&gt;();
    bar.myMap().get("Test").charAt(0); // Can not resolve method "charAt"

    Bar&lt;?&gt; betterbar = new Weird();
    betterbar.myMap().get("Test").charAt(0); // compiles fine

    Weird weird = new Weird();
    weird.myMap().get("Test").charAt(0); // compiles fine
}
</code></pre>