Christian
Christian

Reputation: 1586

Java Generics - Using Lists of Elements implementing an Interface

In Java I have an interface I, a class C and a class D, both implementing I:

interface I
{
    //some method signatures
}

class C implements I
{
    //implement methods from I
}

class D implements I
{
    //implement methods from I
}

Now I create a List holding elements of class C, and a second List holding elements of D:

List<C> c = new LinkedList<C>();
List<D> d = new LinkedList<D>();

I have a method that I want to apply to all Lists that hold elements implementing interface I:

public void modifyList(List<I> l)
{
    //call some method defined in I
}

However, when I try to call that function the compiler throws an error:

public void testModification()
{
    modifyList(c);
    modifyList(d);
}

==> The method modifyList(List<I>) in the type [...] is not applicable for the arguments (List<C>) / (List<D>)

I can get it to work by redefining my List, such that it reads

List<I> c1 = new LinkedList<I>();

But now c1 can hold Elements from both classes C and D, which is something I want to avoid. How can I create a List such that I can define exactly what class' elements it should hold but still use it as a parameter for my function?

Upvotes: 4

Views: 2531

Answers (2)

Mshnik
Mshnik

Reputation: 7032

As you found out, you can't pass List< C > as a parameter to a method expecting List< I >. This is because that method could (legally) add a D to the List< I >, which would violate the generic type invariant of the List< C > .

Changing the method signature to:

public void modifyList(List<? extends I> l)
{
    //call some method defined in I
}

Has the behavior you want: takes list of any generic type that implements I as an argument.

Upvotes: 4

user2982130
user2982130

Reputation:

You can try using

public void modifyList(List<? extends I> l) {
    // ...
}

The type should be a wildcard, meaning any type, as long as its superclass is (...), or in this case, the I class.

Upvotes: 9

Related Questions