Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why it is not possible to create a generic fill method in Java?

Tags:

java

generics

I have the following classes:

abstract class DTO{ }

class SubscriptionDTO extends DTO { }

and the following generic method:

protected void fillList(ResultSet rs, ArrayList<? extends DTO> l)
        throws BusinessLayerException {
    SubscriptionDTO bs;
    try {
        while (rs.next()){
            //initialize bs object...
            l.add(bs); //compiler error here
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }

}

I can't seem to understand why you can't create a generic method for filling DTO subtypes. Am I doing something wrong or is this by design? If so, is there any workaround? Thanks in advance.

like image 772
Igor Zelaya Avatar asked Apr 21 '26 18:04

Igor Zelaya


2 Answers

You should be using <? super DTO> (or <? super SubscriptionDTO>, as Tom Hawtin - tackline points out) as the generic parameter of the ArrayList.

From item 28 of Effective Java (page 28 of the sample chapter [pdf]):

Here is a mnemonic to help you remember which wildcard type to use:

PECS stands for producer-extends, consumer-super.

In other words, if a parameterized type represents a T producer, use <? extends T>; if it represents a T consumer, use <? super T>.

In this case, l is a consumer (you are passing objects to it), so the <? super T> type is appropriate.

like image 160
Michael Myers Avatar answered Apr 24 '26 08:04

Michael Myers


Imagine the following situation, with Foo extends Bar and Zoo extends Bar

List<Foo> fooList = new ArrayList<Foo>();
fooList.addAll(aBunchOfFoos());
aMethodForBarLists(fooList);

then we have the method itself:

void aMethodForBarLists (List<? extends Bar> barList) {
   barList.add(new Zoo());
}

What happens here, is that, even though Zoo does extend Bar, you're trying to add a Zoo in a List<Foo>, which is explicitly made for, and only for, Foos.

This is why the Java spec disallows adding stuff into a <? extends Something> Collection - it can't be sure that, while the syntax seems right, the actual objects would allow adding stuff into the Collection.

like image 25
Henrik Paul Avatar answered Apr 24 '26 06:04

Henrik Paul



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!