2016-06-13 3 views
0

Я действительно борюсь с использованием подстановочных знаков/дженериков. Я пытаюсь создать класс утилиты 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: Я действительно не уверен, что это возможно.

+3

В своем родословном вы сказали 'extends' - вместо этого он должен быть' Data', так как реализуются как 'RecipeData', так и' DemographicData', а НЕ расширяет интерфейс 'Data'. Таким образом, вы используете шаблон «интерфейс как тип». Кстати, вы можете показать, где вы называете 'writeToCsvFile', чтобы узнать, что вы передаете функции? – ishmaelMakitla

+2

Также рассмотрите принцип PECS, как описано [здесь] (http://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super). Резюме. Если вы хотите добавить элементы в коллекцию, используйте 'Collection '. –

+0

Привет, я уверен, что вы используете расширения независимо от того, используется ли этот класс или интерфейс. «NameMappings» и «Процессоры» работают нормально. Я проверил его значительно на не-общую функцию записи, так что это не проблема. Что касается «контейнера», который я передаю, он объявляется в другом классе как «Список container = new ArrayList (); ' –

ответ

0

Вместо использования подстановочного знака для List<? extends Data> container используйте List<Data> container.

+1

Ваш ответ был бы более информативным, если бы вы объяснили, почему это работает. – VGR

Смежные вопросы