Java interface

The add (capture # 2-of? Extends IObject) method in the List type is not applicable for arguments (IDerived)

protected List<? extends IObject> getObjects()
{
    List<? extends IObject> objects = new ArrayList<IObject>();
    for (String id: item_ids)
    {
        IDerived object = (IDerived) readObject(id);
        objects.add(object); #error
    }
    return objects;
}

interface IDerived extends interface IVersionedObject extends interface IObject

If I changed the type of objects to List, then the error will disappear, which makes no sense, because it should make exactly the same set for the return type of the function.

+3
source share
3 answers

Try the following:

protected <T extends IObject> List<T> getObjects() {
    List<T> objects = new ArrayList<T>();
    for (String id: item_ids)
    {
        T object = (T) readObject(id);
        objects.add(object); // NO error
    }
    return objects;
}

EDIT (brief explanation):

Thus, your method will work perfectly with any IObject subtype (lists and rendering inside become universal), and the return type will be inferred from the caller's expectations (as you apparently assumed).

In response to the comment, you can now call the getObjects () method in the following ways:

// This should only be used if readObject() behaves like
// getObjects() and is able to return any requested subtype.
// Otherwise, you'll get a ClassCastException when trying to get
// something from the derivedList in case readObject() put something
// else there (which is not a subtype of IDerived).
List<IDerived> derivedList = getObjects();

// This is the safe way to go in case you don't have
// full control over what readObject() returns.
// But if you're using it like this (all the time), you'd better
// return List<IObject> from getObjects() and get rid
// of generics.
List<? extends IObject> objectList1 = getObjects();
List<IObject> objectList2 = getObjects();
+7
source

, , .

List<? extends IObject> objects = new ArrayList<IObject>();

, , IObject. new ArrayList<IObject>(); rhs, - . , "", .

, objects.add(object); , IDerived, IVersionedObjectSomethingElse. , - , .

List<? extends IObject> objects = null;
if (test) { 
    objects = new ArrayList<IObject>();
}
else {
    objects = new ArrayList<IVersionedObject2>();
}

objects.add( (IDerived) iDerivedObj ); // iDerived *might* not be compatible
+4

Why wildcards? ? extends IObjectUse insteadIDerived

Change this line

List<? extends IObject> objects = new ArrayList<IObject>();

:

List<IDerived> objects = new ArrayList<IDerived>();

And change

protected List<? extends IObject> getObjects()

to

protected List<IDerived> getObjects()
0
source

Source: https://habr.com/ru/post/1790058/


All Articles