Java generics type erasure of method parameters

前端 未结 3 740
南旧
南旧 2021-01-02 10:29

I got this one from a google I/O puzzler talk given by Joshua Bloch. Here\'s the code

 public class Glommer {
      String glom(Collection          


        
相关标签:
3条回答
  • 2021-01-02 10:42

    You can read more about Raw Types to understand it fully

    Basically, raw types are for using legacy code, almost anything in a raw class will become raw itself, in this case those 2 methods.

    So when it is raw there is a method that gets a List and one for Collection so its called the List one, if its not raw, the methods are not raw also and it will call the Collection one because it has the extra information

    0 讨论(0)
  • 2021-01-02 10:55

    The called method is defined at compilation time, not at runtime.

    If you add a parameter to your constructor call, the compiler will have enough information to know that it has to call the first method. Otherwise, it's just as if generics didn't exist. In both case, the called method will always stay the same at runtime.

    EDIT Some people seem to doubt, so here's another example:

    public class Test {
    
        private static void test(Object object) {
            System.out.println("Object method");
        }
    
        private static void test(Integer integer) {
            System.out.println("Integer method");
        }
    
        public static void main(String[] args) {
            Object object = Integer.valueOf(0);
            test(object);
        }
    
    }
    

    The result is:

    Object method
    

    You pass an Integer to your method, but all that the compiler knows at compile time is that it's an object. The jvm doesn't automagically change the method call even though the Object is actually an Integer.

    0 讨论(0)
  • 2021-01-02 10:55

    This is because when new Glommer() is called without generics the Generic<Type>(), all of type matches are removed from the class.

    As strings variable is a List, if it does not have any generic <Type> then it will match the glom(List ints). The type checking doesn't get done till later.

    When we create new Glommer<AnyType> the types are all left in place, so when we pass our strings variable it does type checking. The compiler can now check if it is a List<Integer>, which is not so it gets passed to the glom(Collection<?> obj) method.

    Hope this helps, please ask for any clarification if you need!

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