Непроверенное приведение: подстановочный знак, заключенный в класс, в другой тип, заключенный в класс - PullRequest
1 голос
/ 27 февраля 2020

Я пытаюсь собрать набор классов по критериям аннотации с отражениями (для улучшения производительности):

Reflections reflections = new Reflections(packagePrefix);
Set<Class<Foo>> foos = reflections.getTypesAnnotatedWith(BooAnnotation.class);

Проблема в том, что я получаю Set<Class<?>> вместо Set<Class<Foo>>. Мне удалось проверить, является ли класс типом Foo, отфильтровав коллекцию с помощью .filter(Foo.class::isAssignableFrom). На данный момент я знаю, что я работаю с классами типа Foo. К сожалению, при касте от Class<?> до Class<Foo> я получаю Непроверенный каст , и я хочу избежать этого.

Вот полный блок кода:

Reflections reflections = new Reflections(packagePrefix);
Set<Class<Foo>> foos = reflections.getTypesAnnotatedWith(BooAnnotation.class)
        .stream()
        .filter(Foo.class::isAssignableFrom)
        .map(uncheckedFoo -> {
          @SuppressWarnings("unchecked")
          Class<Foo> foo = (Class<Foo>) uncheckedFoo;
          return foo;
        })
        .collect(Collectors.toSet());

Есть предложения по этому поводу?

1 Ответ

0 голосов
/ 06 марта 2020

Вы можете использовать старый добрый l oop вместо потока , чтобы дать понять компилятору, что каждый элемент равен assignableFrom Foo при приведении. В противном случае он забывает, что на следующем шаге все предметы относятся к типу Foo.

Проверка и приведение заклинаний должны выполняться за 1 шаг

Set<Class<Foo>> foos = new HashSet<>();

for(Class<?> i : reflections.getTypesAnnotatedWith(
                   BooAnnotation.class ) )
{
  if(Foo.class.isAssignableFrom(i))
  {
    foos.add(Foo.class.cast(i)); //cast from Foo.class
  }
}

Примечание : вы можете использовать forEach вместо for(:) l oop

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...