Non-generic reference to generic class results in non-generic return types

后端 未结 3 650
闹比i
闹比i 2021-01-02 13:31

I have a legacy class that the class itself is not a generic but one of its methods return type uses generics:

public class Thing {
    public Collection<         


        
相关标签:
3条回答
  • 2021-01-02 13:45

    Ok, take two, I misunderstood your question.

    When you delcare Thing (this is called a raw type) instead of Thing<?> (parameterized type) the Java compiler strips out all generic arguments, even thogh (as in your case) the generic type of the method has nothing to do with the generic type of the class.

    From the (excellent) Java Generics FAQ:

    Can I use a raw type like any other type?

    Methods or constructors of a raw type have the signature that they would have after type erasure.

    This seemingly inocuous and unobtrusive sentence describes the behaviour in question. You're using Thing as a raw type so the return type is Collection (not Collection<String>) since this is the type after type erasure.

    Confused? Not surprising. Just look at the size of that FAQ. There's probably about three people on earth who nderstand the full implications of Java Generics. Just consider my favourite declaration from the JDK:

    Enum<T extends Enum<T>> 
    

    (Theres an explanation of that in the FAQ too).

    0 讨论(0)
  • 2021-01-02 13:50

    I think this is totally normal. In my opinion using Thing t = new Thing(); for generic enabled class is totally a mistake. When compiler see a generic class used as a class without type parameter, it think it must erase all generic types from that class. This is how you can compile old codes without use of generics in new java compilers and compiler let that old codes use generic enabled classes (e.g. java.util.ArrayList) without any problem. (and this is how java not need separated System.Collection.Generic.List and System.Collection.List like C#). You can run Thing t = new Thing(); with adding a simple type parameter on it, Thing<Object> t = new Thing<Object>();, only thing java compiler needs is making sure that you are using java generic consciously. I never can blame Java for its great backward compatibility.

    I know I am a bit late :D

    0 讨论(0)
  • 2021-01-02 13:57

    It is failing because of erasure. You can read more about it in these Java Tutorials

    0 讨论(0)
提交回复
热议问题