Одно уточнение, просто чтобы убедиться, что вы что-то понимаете: Вы спросили,
Нет ли такой вещи, как тип
стирание необработанных типов во время компиляции
время, когда вся информация, которая должна сделать
с параметрами или типами аргументов
игнорировали?
Люди много говорят о «стирании типов» в Java, частично потому, что стирание типов является одним из многих интересных отличий между Java и C ++, а частично потому, что стирание типов может привести к странным и неожиданным ошибкам при смешивании новых (Java 5 позже) со старым кодом Java.
Однако стирание типов не означает «вся информация, связанная с параметрами или типами аргументов, игнорируется» - это означает нечто гораздо более узкое, чем это. Также, как вы сказали, стирание типов применяется «во время компиляции», но оно применяется после , компилятор проверяет все типы и объявления в вашей программе, чтобы увидеть, есть ли какие-либо ошибки типов.
Первый вопрос: что такое стирание типа? Стирание типов - это то, что происходит только с общими типами. Integer
не является универсальным типом, но ArrayList<T>
является универсальным типом, потому что вы можете объявить ArrayList<Integer>
или ArrayList<String>
. После того, как компилятор завершит проверку типов в вашей программе, чтобы они все совпадали, он отбрасывает всю информацию об универсальных типах, так что ArrayList<Integer>
и ArrayList<String>
оба просто становятся ArrayList
. По этой причине вы можете написать if (foo instanceof String)
на Java, но вы не можете написать if (foo instanceof ArrayList<String>)
: когда этот оператор if
вычисляется во время выполнения, невозможно отличить ArrayList<String>
от ArrayList<Integer>
или из любого другого типа ArrayList
.
Второй вопрос: когда применяется стирание типа? Стирание типа применяется, когда компилятор генерирует скомпилированный код («байт-код») после проверки кода на наличие ошибок компиляции. Это означает, что следующий код выдает ошибку компиляции в Java, хотя Java использует стирание типа:
ArrayList<String> foo = new ArrayList<String>();
foo.add(new Integer(3)); // Error - Compiler knows that String is expected
Я знаю, что не ответил на ваш вопрос, но я хотел убедиться, что вы сначала поняли стирание типа. : -)
Возвращаясь к исходному вопросу: почему класс должен быть объявлен с <E extends Integer>
? Это специально требуется для домашнего задания? Я просто скопировал и вставил ваш код в Eclipse, удалил <E extends Integer>
сверху и заменил все объявления E
на Integer
, и он скомпилировался просто отлично.
(Кстати, по-прежнему проблема с raddoppia
, как вы написали здесь, даже если вы избавились от <E extends Integer>
и получили его для компиляции - вы уже нашли его? Попробуйте протестировать raddoppia
со списком, содержащим более одного элемента, и вы должны увидеть проблему ...)