Community
Participate
Working Groups
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; } }
reason i believe it shouldn't compile: parameterized type 'X' should appear in argument list, whereas here it only appears as method return type
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.
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.
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.
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.