Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Generics: Multiple Bounds

Tags:

java

generics

I have this code:

public class Test {

    public static void main(String[] args) {
        Test t = new Test();
        t.callTest();
    }

    public void callTest() {
        GenericTest gt = new GenericTest<Date>(); // this line don't compile
        gt.test(new Date());
    }

    class GenericTest<T extends Date & List> {
        T x;

        public void test(T y) {
            System.out.println(x.toString());
        }
    }
}

I understand why new GenericTest<Date>() doesn't compile, it is because Date doesn't implement List interface, but if I instantiate GenericTest gt = new GenericTest() without generic, the whole code works, and I don't understand why. The method test expects (T y) where T extends Date and implements List, but it works with gt.test(new Date()).

like image 878
BlackBlaze Avatar asked May 20 '15 07:05

BlackBlaze


1 Answers

When you instantiate like this:

GenericTest gt = new GenericTest() 

you use the raw version of GenericTest type. This means that T type will be replaced with it's first bound (in your case, Date). That's why the method contract of GenericTest#test() has a Date parameter, but not a List one.

Note that every bound, except the first one, must be an interface. Only the first bound can be a class. The reason for this is that it's not possible to have types, which inherit from more that one super-class.

So, since only the first parameter is a class, you won't be able to switch the type-parameters and the following class definition will be invalid:

class GenericTest<T extends List & Date> { }
like image 129
Konstantin Yovkov Avatar answered Oct 30 '22 18:10

Konstantin Yovkov