Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
459 views
in Technique[技术] by (71.8m points)

java - Raw types with generic methods independent of the generic type

This a follow-up to chrert's question Generic classes with Collection getter of other types. If you can come up with a better title to my question, feel free to edit it:

Following code contains a generic class GenericClass<T> with a method of return type T and another method with return type Collection<String>, which is obviously independent of T.

Now, if I instantiate a raw GenericClass (which I would never do, so this question is more a theoretical question, to help understand what's going on) then calling that method in an enhanced for loop won't work, because all generic type information seem to get lost when using raw types. But then, when calling that same method in an assignment, it works (it warns about type unsafety, but it compiles).

In my point of view, either both shouldn't work, or both should work. I don't understand why one works, and the other doesn't. Do you have any hints, or know any parts of the JLS that explain this behavior?

public class GenericClass<T>  {

    T doSomething() {
        return null;
    }

    Collection<String> getCollection() {
        return Collections.emptyList();
    }

    public static void main(String[] args) {
        GenericClass raw = new GenericClass();
        // This will not compile (Error message below)
        for (String str : raw.getCollection()) {
            // Type mismatch: cannot convert from element type Object to String
        }
        // This is only a warning:
        // Type safety: The expression of type Collection needs unchecked conversion to conform to Collection<String>
        Collection<String> coll = raw.getCollection();
        for (String string : coll) {
            // works just fine
        }
    }
}

There is a related question, which, together with the accepted answer here, explains what's going on pretty good: Why won't this generic java code compile?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In the first case, raw.getCollection() returns a raw Collection. JLS 14.14.2 specifies the type checking for the enhanced for loop:

If Type (in the FormalParameter production) is a reference type, then TargetType is Type; otherwise, TargetType is the upper bound of the capture conversion of the type argument of I, or Object if I is raw.

(emphasis added)

In the second case, you're explicitly assigning a raw type to a generic type, which is allowed with a warning like normal.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...