Search code examples
javagenericstype-parameter

Why does this code only pass compilation after adding an unused generic type parameter to the class?


This code doesn't pass compilation:

class SomeClass {
    void doSomethink(List<Integer> params) { }
}

class AnotherClass {
    public void method() {
        SomeClass someClass = new SomeClass();
        List<Long> list = new ArrayList<>();

        someClass.doSomethink(list);
    }
}

But if SomeClass contains an unused type parameter E then this code will pass compilation successfully:

class SomeClass<E> {
    void doSomethink(List<Integer> params) { }
}

class AnotherClass {
    public void method() {
        SomeClass someClass = new SomeClass();
        List<Long> list = new ArrayList<>();

        someClass.doSomethink(list);
    }
}

Why does this make a difference? E is not used.


Solution

  • You are trying to pass a List<Long> to a method that expects a List<Integer>. A List<Long> is not a sub-class of List<Integer>, so it's not allowed.

    When you make your SomeClass class generic (by adding E), and then instantiate it with the raw type SomeClass, all the generic type parameters of all the methods and their arguments are erased, and the compiler allows you to pass any List to the doSomethink() method.

    Note that you'll get the same compilation error in your second snippet if you change it to (i.e. don't use a raw SomeClass type):

    class SomeClass<E> {
        void doSomethink(List<Integer> params) { }
    }
    
    class AnotherClass {
        public void method() {
            SomeClass<Integer> someClass = new SomeClass<>();
            List<Long> list = new ArrayList<>();
    
            someClass.doSomethink(list);
        }
    }