Как уже говорилось, Java является строго типизированным языком, аэто означает, что каждое выражение и каждая переменная имеет строго определенный тип уже на момент компиляции. Тип устанавливается на основе структуры применяемых выражений и типов литералов, переменных и методов, используемых в этих выражениях.
Например:
long а=3;
а = 5+'АЧа;
print("a="+Math.rouncl(a/2F));
Рассмотрим, как в этом примере компилятор устанавливает тип тихого выражения и какие преобразования (conversion) типов необходимо осуществить при каждом действии.
• В первой строке литерал 3 имеет тип по умолчанию, то есть int. При присвоении этого значения переменной типа longнеобходимо провести преобразование.
• Во второй строке сначала производится сложение значений типа int и char. Второй аргумент будет преобразован так, чтобы операция проводилось с точностью в 32 бита. Второй оператор сложения опять потребует преобразования, так как наличие переменной аувеличивает точность до 64 бит.
•в третьей строке сначала будет выполнена операция деления, для чего значение long надо будет привести к типу float, так как второй операнд — дробный литерал. Результат будет передан в метод Math.round, который произведет математическое округление и вернет целочисленный результат типа int. Это значение необходимо преобразовать текст, чтобы осуществить дальнейшую конкатенацию строк. Как будет показано ниже, эта операция проводится в два этапа — сначала простой тип приводится к объектному классу "обертке" (в данном случае int к Integer), а затем у полученного объекта вызывается метод toString(), что дает преобразование к строке.
Данный пример показывает, что даже простые строки могут содержать многочисленные преобразования, зачастую незаметные для разработчика. Часто бывают и такие случаи, когда программисту необходимо явно изменить тип некоторого выражения или переменной, например, чтобы воспользоваться подходящим методом или конструктором.
Вспомним уже рассмотренный пример:
byteb=1;
byte c={byte)-b;
int i=c;
Здесь во второй строке необходимо провести явное преобразование, чтобы присвоить значение типа byte переменной типа int. В третьей же строке обратное приведение производится автоматически, неявным для разработчика образом.
Рассмотрим сначала, какие переходы между различными типами можно осуществить.