Convert from Iterator<T> to Iterator<U> where T is a subclass of U

Mischa :

Given a class T which is a subclass of U, is it safe to cast Iterator<T> to Iterator<U>? And assuming that the cast be safe, are there more elegant (and warning-free) ways of doing it other than:

Iterator<T> it = <insert your Iterator<T> here...>;
Iterator<U> it2 = (Iterator<U>)(Iterator<? extends U>)it;

My reasoning why the cast is not dangerous is this:

  1. Iterator<?> does not support inserting elements, so there is no danger of corrupting the underlying data structure by using Iterator<U> instead of Iterator<T>;
  2. Consumer<? super U> is convertible to Consumer<? super T> but not vice versa. Hence, Iterator<U>::forEachRemaining(Consumer<? super U> action) will accept a subset of all actions eligible for the same method in Iterator<T> and, in particular, does not introduce a way of executing actions not supported by Iterator<T>;
  3. Iterator<U>::remove() is equivalent to Iterator<T>::remove();
  4. Iterator<U>::next() returns a superclass of T;
khelwood :

I agree, I don't see any reason it should be unsafe.

I believe that

Iterator<U> it2 = (Iterator) it;

should be sufficient to make the cast compile, but you would still have to suppress the warnings if you wanted it without a warning. Suppressing a warning is fine if you understand the reason for the warning and know it will not apply in this case.

Perhaps whatever code you are using that demands an Iterator<U> should be refactored to accept Iterator<? extends U> instead.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=70554&siteId=1