Ive расширил некоторые базовые классы Apache Olingo 4 (все еще в разработке), чтобы обеспечить более сильный набор. Тем не менее, использование дженериков вызывает ошибку, которую я не ожидал.
У меня есть параметр типа E, который расширяет FooODataEntity, который, в свою очередь, реализует интерфейс ODataEntity. Поскольку FooODataEntity является ODataEntity (более конкретным), я бы ожидал, что это будет компилироваться без проблем. Однако getEntities() имеет ошибку компиляции, как показано в приведенном ниже коде.
Кроме того, я ожидал бы, что сможет указать List<E>
как возвращаемый тип для моего переопределения getEntities()
но затем я получаю ошибку компиляции:
'getEntities()' in 'com.foo.restapi.client.olingo.FooEntitySet' clashes with 'getEntities()' in 'org.apache.olingo.commons.api.domain.v4.ODataEntitySet'; attempting to use incompatible return type
Что мне здесь не хватает?
FooODataEntitySet:
package com.foo.restapi.client.olingo;
import com.foo.restapi.client.FooODataEntity;
import com.foo.restapi.client.exceptions.FooRuntimeException;
import org.apache.olingo.commons.api.domain.v4.ODataAnnotation;
import org.apache.olingo.commons.api.domain.v4.ODataEntity;
import org.apache.olingo.commons.api.domain.v4.ODataEntitySet;
import org.apache.olingo.commons.core.domain.AbstractODataEntitySet;
import java.lang.reflect.Constructor;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
public class FooEntitySet<E extends FooODataEntity>
extends AbstractODataEntitySet implements ODataEntitySet {
private final List<E> entities = new ArrayList<E>();
public FooEntitySet() {
super();
}
@Override
public List<ODataEntity> getEntities() {
// compile error
// Incompatible types. Found: 'java.util.List<E>',
// required: 'java.util.List<org.apache.olingo.commons.api.domain.v4.ODataEntity>'
return entities;
}
}
FooODataEntity:
package com.foo.restapi.client;
public class FooODataEntity extends AbstractODataPayload
implements ODataEntity, ODataSingleton {
// code not shown
}
Там причина, по которой вы не можете этого сделать. Хотя FooODataEntity
является ODataEntity
, List<FoodODataEntity>
не является List<ODataEntity>
.
Давайте рассмотрим это более подробно:
Скажем, у меня есть этот класс:
public class BaconODataEntity implements ODataEntity {
// Pretend I implement all the ODataEntity things
}
Я могу добавить экземпляр BaconODataEntity
в List<BaconODataEntity>
и List<ODataEntity>
... но не в List<FooODataEntity>
.
Таким образом, просто позволяя вам List<FooODataEntity>
в List<ODataEntity>
будет уничтожать тот самый тип безопасности, который генерируют дженерики, поскольку я мог бы добавить к нему BaconODataEntity
Итак, как вы это исправите? Ну, если вам абсолютно необходим ваш список, который будет List<E extends FooODataEntity>
, создайте новый List и скопируйте в него элементы и верните этот список.
FooODataEntity
для другого метода, поэтому я скопировал в новый список типа ODataEntity
как вы предложили.