// int i = (Integer) raw.getobO;
В этом операторе присваивания в объекте raw определяется значение переменной ob, которое приводится к типу Integer. Но дело в том, что в объекте raw содержится не целое число, а значение типа Double. На стадии компиляции этот факт выявить невозможно, поскольку тип объекта raw неизвестен. Следовательно, ошибка возникнет на стадии выполнения программы.
В следующих строках кода ссылка на объект класса Gen базового типа присваивается переменной strOb (ссылки на объект типа Gen
strOb = raw; // Допустимо, но потенциально ошибочно.
// String str = strOb.getob; // Ошибка при выполнении программы.
Само по себе присваивание синтаксически правильно, но логически сомнительно. Переменная strOb ссылается на объект типа Gen
raw = iOb; // Допустимо, но потенциально ошибочно. // d = (Double) raw.getobO; // Ошибка при выполнении программы. В данном случае ссылка на объект обобщенного типа присваивается переменной базового типа. И это присваивание синтаксически правильно, но приводит к ошибке, возникающей во второй строке кода. В частности, переменная raw указывает на объект, содержащий значение типа Integer, но при приведении типов предполагается, что он содержит значение типа Double. И эту ошибку также нельзя выявить на стадии компиляции, а проявляется она при выполнении программы. В связи с тем что использование базовых типов сопряжено с потенциальными ошибками, проявляющимися при выполнении программы, компилятор javac выводит в подобных случаях сообщения, предупреждающие об отсутствии проверки типов, когда базовый тип используется в обход механизма типовой безопасности. Такие сообщения будут получены и при компиляции рассматриваемой здесь программы. Причиной их появления станут следующие строки кода:
Gen raw = new Gen(new Double(98.6));
strOb = raw; // Допустимо, но потенциально ошибочно. В первой из этих строк кода содержится обращение к конструктору класса Gen без указания аргумента типа, что приводит к выдаче компилятором соответствующего предупреждения. А при компиляции второй строки предупреждающее сообщение возникнет из-за попытки присвоить переменной, ссылающейся на объект обобщенного типа, ссылки на объект базового типа. На первый взгляд может показаться, что предупреждение об отсутствии проверки типов может вызвать и приведенная ниже строка кода, но этого не произойдет,
raw = iOb; // Допустимо, но потенциально ошибочно. В этом случае компилятор не предупреждает пользователя, потому что такое присваивание не приводит к еще большей потере типовой безопасности по сравнению с той, которая произошла при создании переменной raw базового типа. Из всего изложенного выше можно сделать следующий вывод: пользоваться базовыми типами следует весьма ограниченно и только в тех случаях, когда устаревший код требуется объединить с новым, обобщенным кодом. Базовые типы — лишь средство для обеспечения совместимости с устаревшим кодом. Они не должны присутствовать во вновь разрабатываемом коде. ## Выводимость типов с помощью ромбовидного оператора Начиная с версии JDK 7 появилась возможность сократить синтаксис, применяемый для создания экземпляра обобщенного типа. В качестве примера обратимся к классу TwoGen, представленному в начале этой главы. Ниже для удобства приведена часть его объявления. Обратите внимание на то, что в нем определяются два обобщенных типа данных.