Вы сказали:
Но после удаления `при создании объекта myClassIterator в iterator () ошибка исчезает и код работает без проблем
При удалении типапараметр <T>
вы используете необработанный тип из MyClassIterator
.Ошибка исчезает, потому что
Для обратной совместимости разрешено присвоение параметризованного типа его необработанному типу.
Используя необработанные типы, вы, по сути, получаете предварительное поведение
В таком случае iterator()
вернет MyClassIterator
, который возвращает элементы типа Object
.
Это работает, потому что
, если вы назначаете необработанный тип параметризованному типу, вы получаете предупреждение:
Таким образом, вы получаете предупреждение, но неошибка времени компиляции.
Но зачем указывать универсальный тип, дайте мне эту ошибку?
public Iterator<T> iterator() {
return new MyClassIterator<T>(n, array); // Here's my error!
}
Здесь вы пытаетесь передать массив с компонентомвведите Object
в конструктор MyClassIterator(int n, T[] array)
.Этот конструктор принимает массив типа T
.Являются ли Object
s экземплярами типа T
?Это может быть, но не обязательно.Но чтобы вызвать этот конструктор, он должен быть.
Как заполнить этот пробел?
Поле array
должно быть объявлено с типом компонента T
.
private T[] array;
Но тогда array = new Object[size];
не будет работать , потому что
Вы не можете создавать массивы параметризованных типов.
Как решить эту проблему?
Либо, передав Class<T>
в конструктор, как @ohlec предлагает .
Другой вариант - следовать примеру Stream.toArray(IntFunction<T[]> generator)
:
public MyClass(int size, IntFunction<T[]> generator) {
array = generator.apply(size);
n = 0;
}
Чтобы создать MyClass<String>
экземпляр с n
= 5
, мы вызываем конструктор так:
MyClass<String> strings = new MyClass<>(5, String[]::new);
В этом случае мы передаем неявный аргумент типа String
вконструктор.