Я действительно борюсь с использованием подстановочных знаков/дженериков. Я пытаюсь создать класс утилиты FileManager
, который может принимать пользовательские Java-компоненты и писать чтение/запись компонента в файл. Просто, чтобы привести пример, у меня есть интерфейс под названием Data
, который реализован RecipeData
и DemographicData
. Я использую Super CSV
для преобразования CSV-файла в Java-компонент. Вот мой метод чтения, основанный на кодексе обучения, который я нашел от Super CSV
.Java: проблема с подстановочными знаками/генериками
public interface Data { method declarations }
public class RecipeData implements Data { class stuff goes here }
public class DemographicData implements Data { class stuff goes here }
final public class FileManager {
public static void parseCsvFile(String filename, CellProcessor[] processors, String[] nameMappings, List<? extends Data> container) {
ICsvBeanReader beanReader = null;
try {
beanReader = new CsvBeanReader(new FileReader(filename), CsvPreference.STANDARD_PREFERENCE);
Data data;
while((data = beanReader.read(Data.class, nameMappings, processors)) != null) {
container.add(data);
}
} finally {
if (beanReader != null) {
beanReader.close();
}
}
}
}
В настоящее время я получаю следующее сообщение об ошибке:
The method add(capture#1-of ? extends Data) in the type List is not applicable for the arguments (Data)
я не уверен, что я делаю это вообще возможно. Идея состоит в том, что передаваемый container
может иметь тип RecipeData
или DemographicData
. Поэтому я думаю, что одна проблема заключается в том, что data
должен быть двух типов.
Может ли кто-нибудь дать отзыв о том, как я могу это исправить, или если он даже будет работать?
EDIT: Я действительно не уверен, что это возможно.
В своем родословном вы сказали 'extends' - вместо этого он должен быть' Data', так как реализуются как 'RecipeData', так и' DemographicData', а НЕ расширяет интерфейс 'Data'. Таким образом, вы используете шаблон «интерфейс как тип». Кстати, вы можете показать, где вы называете 'writeToCsvFile', чтобы узнать, что вы передаете функции? – ishmaelMakitla
Также рассмотрите принцип PECS, как описано [здесь] (http://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super). Резюме. Если вы хотите добавить элементы в коллекцию, используйте 'Collection super Data> '. –
Привет, я уверен, что вы используете расширения независимо от того, используется ли этот класс или интерфейс. «NameMappings» и «Процессоры» работают нормально. Я проверил его значительно на не-общую функцию записи, так что это не проблема. Что касается «контейнера», который я передаю, он объявляется в другом классе как «Список container = new ArrayList(); ' –