у нас есть два универсальных типа: один для подтипа коллекции, другой для типа элемента коллекции.может работать следующий код:
private static <C extends Collection<E>, E>
C create(Class<C> cls) throws Exception
{
return cls.newInstance();
}
пример использования.предупреждений нет.
Class<LinkedList<String>> clazz = ...;
LinkedList<String> result = create(clazz);
Теперь возникает вопрос, как мы можем получить clazz
?Вы должны убедительно убедить компилятор:
List<String> list = new LinkedList<String>();
clazz = (Class<LinkedList<String>>)list.getClass();
clazz = (Class<LinkedList<String>>)(Class<?>)LinkedList.class;
у нас может быть вспомогательный метод для облегчения приведения типов:
public static <C extends Collection, E, T extends Collection<E>>
Class<T> type(Class<C> classC, Class<E> classE)
{
return (Class<T>)classC;
}
//usage:
clazz = type(LinkedList.class, String.class);
result = create(clazz);
Забавно, что вы получите:
Class<LinkedList<LinkedList<String>>> clazz2;
LinkedList<LinkedList<String>> result2;
clazz2 = type(LinkedList.class, clazz);
result2 = create(clazz2);
Но в какой-то момент мы должны остановить эту глупую игру.Типичная типизация должна помочь нам, а не пытать нас.Когда он становится слишком громоздким и делает невозможным чтение наших программ, просто бросьте его.Используйте чертовски грубые типы, с которыми мы счастливо жили годами.