Shevek (shevek) wrote,

A java erasure puzzler:

If I have a Class<T> c, then c.cast(o) is of type T.

If I have a Class<? extends T> then (type erasure seems to suggest) c.cast(o) is also of type T, not of the type Capture of ? extends T. This means, with reference to the previous post about instance maps, that one cannot cleanly call a method of type <T>(Class<T>, T) with c, c.cast(o) as one might expect. I believe this is because javac is erasing the type too soon and if the capture type were to be preserved, the statement would compile correctly and safely.

Normally when I find bugs in javac, they're out and out bugs (although, as you might guess, usually somewhere in the fringes of the type system). I can't make up my mind about this one. Can anyone express an opinion please?

A fuller description of the overall pattern is available here; note especially tijntje's thread, in which I think we divine that even in a language without erasure, the full construct cannot be statically typechecked, so please don't rant about erasure in general unless you also provide the typed lambda calculus solution (which I suspect is immediate for someone versed in the art).

Edit: If you think about it, a Class<? extends T> can return a Constructor<? extends T>, so the capture is preserved in a returned parameterized type. It's only in the case where the capture is directly the return type of the method that this bug arises. In that case, it's natural to assume that the value will (for example) be assigned to a variable which has a concrete type T, since one cannot declare a variable of capture type unless it's the aforementioned parameter. This case of the proof of equality of two types might easily have been forgotten by the programmer.

Later edit: Test code as submitted to Sun:

public class TestGenerics {
    void test() {
        Class<? extends String> type = null;
        Object value = null;
        apply(type, type.cast(value));

    <T> void apply(Class<T> c, T obj) {
  • Post a new comment


    default userpic

    Your reply will be screened

    Your IP address will be recorded 

    When you submit the form an invisible reCAPTCHA check will be performed.
    You must follow the Privacy Policy and Google Terms of use.