Общий тип коллекции должен иметь значение только в том случае, если в нем действительно есть объекты, верно? Так не проще ли просто сделать:
Collection<?> myCollection = getUnknownCollectionFromSomewhere();
Class genericClass = null;
Iterator it = myCollection.iterator();
if (it.hasNext()){
genericClass = it.next().getClass();
}
if (genericClass != null) { //do whatever we needed to know the type for
Во время выполнения нет такого понятия, как универсальный тип, но объекты внутри во время выполнения гарантированно совпадают с типом объявленного универсального, поэтому достаточно просто проверить класс элемента перед его обработкой.
Еще одна вещь, которую вы можете сделать, - это просто обработать список, чтобы получить членов правильного типа, игнорируя других (или обрабатывая их по-другому).
Map<Class<?>, List<Object>> classObjectMap = myCollection.stream()
.filter(Objects::nonNull)
.collect(Collectors.groupingBy(Object::getClass));
// Process the list of the correct class, and/or handle objects of incorrect
// class (throw exceptions, etc). You may need to group subclasses by
// filtering the keys. For instance:
List<Number> numbers = classObjectMap.entrySet().stream()
.filter(e->Number.class.isAssignableFrom(e.getKey()))
.flatMap(e->e.getValue().stream())
.map(Number.class::cast)
.collect(Collectors.toList());
Это даст вам список всех предметов, чьи классы были подклассами Number
, которые вы затем сможете обрабатывать по мере необходимости. Остальные элементы были отфильтрованы в другие списки. Поскольку они находятся на карте, вы можете обрабатывать их по своему усмотрению или игнорировать их.
Если вы хотите полностью игнорировать предметы других классов, это становится намного проще:
List<Number> numbers = myCollection.stream()
.filter(Number.class::isInstance)
.map(Number.class::cast)
.collect(Collectors.toList());
Вы даже можете создать служебный метод, чтобы гарантировать, что список содержит ТОЛЬКО те элементы, которые соответствуют определенному классу:
public <V> List<V> getTypeSafeItemList(Collection<Object> input, Class<V> cls) {
return input.stream()
.filter(cls::isInstance)
.map(cls::cast)
.collect(Collectors.toList());
}