Bug 81912 - [1.5] 3.1M4 invalid generics class compiles
Summary: [1.5] 3.1M4 invalid generics class compiles
Status: RESOLVED INVALID
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: 3.1 M5   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-12-26 14:30 EST by mike andrews CLA
Modified: 2005-02-15 05:37 EST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description mike andrews CLA 2004-12-26 14:30:29 EST
i don't believe the following class should compile, since parameterized type 'X'
is not parameterized correctly; as it is, it throws a compiler warning that
doesn't make sense either:

public class Converter {

    public static <X> X convertObject(Object o) {
        return (X) o;
    }

}
Comment 1 mike andrews CLA 2004-12-26 14:42:36 EST
reason i believe it shouldn't compile: parameterized type 'X' should appear in
argument list, whereas here it only appears as method return type
Comment 2 Jerome Lanneluc CLA 2005-01-04 06:52:00 EST
Why are you saying that the parameter type X should appear in the paramaters of
the method ? Nothing in the JLS 3 enforces that. Also note that javac compiles
this without error either.
Comment 3 mike andrews CLA 2005-01-04 10:59:43 EST
sure, it compiles, but doesn't the following seem a bit pathological, in that
there's no rational type-safety at all?

package test;

public class Converter {

    public static <X> X convertObject(Object o) {
        return (X) o; // COMPILER WARNING: "Unnecessary cast from Object to X"
    }
    
    public static void main(String[] args) {
        Object x = new Object();
        String string = convertObject(x); // COMPILES FINE, NO WARNING
        Integer integer = convertObject(x); // COMPILES FINE, NO WARNING
    }
    
}

so the two convertObject() invocations fail at runtime with class-cast
exceptions; i think they should fail at compile-time (JLS or not), since 'x' is
obviously not a java.lang.String nor a java.lang.Integer.


Comment 4 Felix Pahl CLA 2005-02-06 19:43:07 EST
Mike, you're right that the compiler warning about an unnecessary cast doesn't
make sense. This has been reported in Bug 78084. However, regarding your
statement that x is "obviously" neither a String nor an Integer, I think you
misunderstand how such things are checked in Java. Once the new Object () has
been assigned to a reference variable of type Object, the compiler doesn't (and
isn't supposed to) carry along information about what this variable refers to.
Since a reference of type Object can refer to an object of any type, a cast to
any type is allowed, including the variable type X. Javac is correct in
compiling this code without error. You can find all the details of how these
checks are performed in the Language Specification at
http://java.sun.com/docs/books/jls/java_language-3_0-mr-spec.zip.
Comment 5 mike andrews CLA 2005-02-07 07:32:54 EST
thanks very much for the explanation. i am now curious to see the JLS wording
which is responsible for this; somehow it still seems a bit pathalogical,
perhaps even sort of a loophole in the spec, now that there are generics?
whenever i put myself in gosling's shoes, who i know is a rational man, i can't
help but see him cringe every time he sees the following three statements
compile without error or even warning: Object x = new Object(); String string =
convertObject(x); Integer integer = convertObject(x);

reason is: the <X> generics parameter has nothing to do with the test.Converter
class or instance or parameters, and can only come from the environment from
which its called (sort-of like double-dispatch, a feature absent in java). if
the <X> parameter would have also been in the method's parameter list, at least
the test.Converter object would be able to vary the return class in response;
but it can't, since there is no such parameter.