Ошибка не появляется, потому что код все еще "действителен". Java Обобщения - это модный способ обработки объектов и улучшения проверки типов. Каждый раз, когда вы используете обобщенный c, при компиляции кода Java преобразует их в явное приведение. Основная причина связана с унаследованными версиями Java до того, как дженерики были представлены, поэтому Java обрабатывает их как класс "Object" и затем приводит их за вас при необходимости.
Например, в вашем. * В файле 1018 * вы пишете следующий код:
String hello = new String();
ArrayList<String> list = new ArrayList<>();
list.add(hello);
Object noCastRequired = list.get(0);
String castRequired = list.get(0);
В своем относительном .class-файле Java напишет:
String hello = new String();
ArrayList<String> list = new ArrayList();
list.add(hello);
Object noCastRequired = list.get(0);
String castRequired = (String)list.get(0);
Если вы собираетесь проверить свой скомпилированный код, вы можете видеть, что выражение все еще является допустимым оператором кода, но у вас будут ошибки и проблемы, если вы попытаетесь «использовать» это поле в методе, где требуется «тип»; Оператор print принимает объектный класс в качестве параметра, поэтому Java не собирается его приводить.
Пример:
class Scratch {
public static void main(String[] args) {
Root<FirstLevel> correct = new Root<>();
Root<FirstLevelChild> iAmNotValid = new Root<>(); // No error
Root<SecondLevel> iAmNotValidToo = new Root<>(); // No error
System.out.println(correct.field.first); // Ok
System.out.println(iAmNotValid.field.first); // Ko, because java.lang.ClassCastException: FirstLevel cannot be cast to FirstLevelChild
System.out.println(iAmNotValidToo.field.second);
}
}
class Root<T> {
public T field = (T) new FirstLevel();
}
class FirstLevel {
public String first = "First";
}
class SecondLevel {
public String second = "Second";
}
class FirstLevelChild extends FirstLevel {
}