Почему использование необработанных переменных типа влияет на подписи без ссылки на параметры типа?
Взгляд в другой question Я столкнулся с этим интригующим поведением компилятора Sun-Oracle 1.8.0_112 (я не тестировал его с другими):
import java.util.List;
interface Alpha<T> {
List<Integer> intList();
}
interface Beta {
List<Integer> intList();
}
class Main {
public static void main(String[] args) {
Alpha rawAlpha = null;
Alpha<Character> charAlpha = null;
Alpha<?> qmAlpha = null;
Beta beta = null;
for (Integer i : charAlpha.intList()) {}
for (Integer i : qmAlpha.intList()) {}
for (Integer i : beta.intList()) {}
for (Integer i : rawAlpha.intList()) {}
}
}
Только компилятор не работает в последнем цикле for:
error: incompatible types: Object cannot be converted to Integer
for (Integer i : rawAlpha.intList()) {}
^
1 error
Поэтому, несмотря на то, что тип возвращаемого списка intList()
List<Integer>
в Alpha
не зависит от параметра типа T
, кажется, что <Integer>
стирается во время компиляции.
Обратите внимание: если мы объявим не общий интерфейс Beta
, теоретически эквивалентным тому, чтобы ссылаться на raw Alpha
, проблем нет.
Является ли это ожидаемым поведением? может ли кто-нибудь указать параграф на языке спецификации, который будет охватывать этот момент? Если это не ошибка, по крайней мере, она кажется антиинтуитивной и непродуктивной; возможно, делается ради обратной сопоставимости?
Ответы
Ответ 1
Бит JLS, который говорит это (немного неясно), находится в JLS 4.8:
Тип конструктора (§8.8), метод экземпляра (§8.4, §9.4) или нестатическое поле (§8.3) необработанного типа С, которое не унаследовано от его суперклассов или суперинтерфейсов, является необработанным типом что соответствует стиранию его типа в общем объявлении, соответствующем C.
Итак, поскольку rawAlpha
является сырым типом, типом rawAlpha.intList
является стирание List<Integer> intList()
. Это стирание List intList()
.
Что касается причин, у меня нет ссылки, но сырые типы действительно на самом деле в Java для обратной совместимости. Это означает, что они должны работать только так, как раньше, до дженериков; то, о чем вы просите, это код, который работает немного лучше, чем раньше. Это не необоснованно, но это не то, что они решили.: -)