2016-08-23 2 views
1

быстрый вопрос о создании объектов при предоставлении объекта класса. Или, может быть, мне нужно пойти по этому поводу по-другому. Во-первых, из моего плана я пишу метод, который будет принимать массив объектов File и считывать каждый из них в Set, где каждый набор затем добавляется в список и возвращается список. Ниже то, что у меня есть:Создание объекта из заданного объекта класса в Java

private static List<Set<String>> loadFiles(File[] files, Class whatType, Charset charSet){ 
    List<Set<String>> setList = new ArrayList<Set<String>>(files.length); 

    try { 
     for(File f : files){ 
      BufferedInputStream bs = new BufferedInputStream(new FileInputStream(f)); 
      InputStreamReader r = new InputStreamReader(bs, charSet); 
      BufferedReader br = new BufferedReader(r); 

      Set<String> set = new HashSet<>(); //This is the problem line 
      String line = null; 

      while((line = br.readLine()) != null){ 
       set.add(line.trim()); 

      } 

      br.close(); 
      setList.add(set); 
     } 

     return setList; 
    } catch (FileNotFoundException e) { 
     //Just return the empty setlist 
     return setList; 
    } catch (IOException e) { 
     //return a new empty list 
     return new ArrayList<Set<String>>(); 
    } 
} 

Но то, что я хочу, чтобы позволить пользователю способа указать тип набора для создания экземпляра (если он содержит строки, конечно). Это и есть параметр «whatType».

Все мое исследование привело меня к тому, как создать экземпляр объекта с именем класса, но на самом деле это не то, что я здесь.

+1

Вы имеете в виду, например, 'HashSet' против' TreeSet'? –

+1

Почему? Обычно на Java ожидается, что вы вернете свой собственный новый набор из такого метода. Если есть веская причина использовать версию вызывающего абонента, попросите их передать ее. – chrylis

+0

@chrylis Основная причина этого заключается в том, что внутри проекта, над которым я работаю, мы много загружаем файлы и сохраняем эти строки в наборах : Hash, Tree, наши собственные классы, которые реализуют Set. И тип используемого набора зависит от ситуации. Это просто позволяет нам упростить базу кода и написать меньше шаблонов с литьем. Это касается случаев, когда важная реализация важна. – Hangman4358

ответ

1

Если предположить, класс имеет без аргументов доступный конструктор, вы в основном newInstance() звонку:

Set<String> set = (Set<String) whatType.newInstance(); 

Обратите внимание, что если вы определили whatType как Class<? extends Set> вместо того, чтобы просто сырой Class, вы может избавиться от этого уродливого литья тоже.

+0

Я решил принять этот ответ, потому что я все еще использую Java 7 для этого проекта, и он отлично работал – Hangman4358

2

Если вы можете использовать Java8, вы можете легко решить эту проблему. Объявите метод следующим образом:

private static List<Set<String>> loadFiles(File[] files, Supplier<Set> setSupplier, Charset charSet) 

Изменить вашу проблему линии:

Set<String> set = setSupplier.get(); 

Затем в каждом вызове этого метода setSupplier парам может быть легко обеспечивается с помощью ссылки метода: HashSet: : new, TreeSet :: new ...

+0

Я должен был указать, что я все еще застрял в мире Java 7, но для 8 это действительно здорово и работает, когда я его тестировал в небольшом проектном проекте – Hangman4358

2

Как насчет использования метода Class.newInstance()? Я закодировал простой пример для вас:

public <T extends Set> void myMethod(Class<T> type) { 
 
    T object; 
 
    try { 
 
    object = type.newInstance(); 
 
    } catch (InstantiationException e) { 
 
    e.printStackTrace(); 
 
    } catch (IllegalAccessException e) { 
 
    e.printStackTrace(); 
 
    } 
 
} 
 

 
public void caller() { 
 
    myMethod(HashSet.class); 
 
}

это то, что вы ищете?

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