Приведение итератора с обобщениями в итератор с подстановочными знаками - PullRequest
0 голосов
/ 24 июня 2018

Я пытаюсь привести Iterator<Map.Entry<String,Option<T>>> к Iterator<Map.Entry<String,Option<?>>>, потому что не могу объявить универсальный T в своем коде.Я получаю следующую ошибку:

Несоответствие типов: невозможно преобразовать из Iterator

>> в Iterator
>>

У меня есть класс OptionSet<T>, от которого я получаю Iterator от:

public class OptionSet<T> implements Iterable<Map<String,Option<T>>> {

  private final Map<String,Option<T>> options;

  // ...

  public final Iterator<Map<String,Option<T>>> iterator() {
    return options.entrySet().iterator();
  }

}

Я использую OptionSet<?> в своемкод, поэтому у меня нет универсального типа.
Я пытаюсь получить Iterator из этого класса:

final Iterator<Map.Entry<String,Option<?>>> iterator = optionSet.iterator();

По какой-то причине Java не позволяет этого.Кастинг также не разрешен.Однако работает следующее:

@SuppressWarnings({ "unchecked", "rawtypes" })
final Iterator<Map.Entry<String,Option<?>>> iterator = (Iterator) optionSet.iterator();

Итак, почему это работает, но Java не разрешает обычное преобразование или приведение?

1 Ответ

0 голосов
/ 24 июня 2018

Вам не нужно создавать тип T в вашем коде.Это просто означает "Тип".Это означает, что это типизированный объект.Как работает назначение, зависит от того, как создается ваш OptionSet.Например, это работает:

    OptionSet<String> optionSet = new OptionSet<>();
    final Iterator<Map.Entry<String,Option<String>>> iterator = optionSet.iterator();

И это работает, потому что вы не назначаете тип для универсального в OptionSet, когда он создается, поэтому он не имеет типов с общей точки зрения, поэтому захват в назначении можетбыть чем-нибудь

        OptionSet optionSet = new OptionSet<>();
        final Iterator<Map.Entry<String,Option<?>>> iterator = optionSet.iterator();

И если по какой-то причине вы не знаете, что это за тип при создании экземпляра, вы все равно можете использовать его в общем.Просто используйте определение общего типа, и оно будет содержать все, что было передано. Например:

public void testUnknownTypeOptionSet(OptionSet<T> testOptionSet) {

        final Iterator<Map.Entry<String,Option<T>>> iterator = testOptionSet.iterator();
    }
...