Глава 5.4. Преобразования типов5.4.1. Виды преобразованийКаждое выражение в Java имеет тип, который определяется структурой выражения и типами составляющих его операндов (констант, переменных и методов). Однако, иногда нам может потребоваться явное преобразование выражения в другой тип. Кроме того, в некоторых ситуациях исполняющая система Java сама неявно проводит такие преобразования. Преобразование типа Т1 в тип T2 позволяет выражению типа T1 трактоваться в период компиляции как выражение типа T2. В одних случаях это чисто синтаксическая конструкция, не влияющая на генерируемый код, в других преобразование типа требует дополнительных действий в период выполнения по изменению значения выражения или дополнительных проверок правильности применяемого преобразования. Примеры:
Далее в этой главе приведена классификация всех возможных преобразований типов, а затем классификация контекстов в которой они могут использоваться. 5.4.1.1. Расширяющие преобразования чиселРасширяющие преобразования чисел — это преобразования числового типа в "больший" числовой тип, которые считаются безопасными, т. к. не приводят к потере величины преобразуемого значения. Такими преобразованиями в Java являются:
В действительности, преобразование целого значения в плавающее может привести к потере точности, т. е. к потере значащих цифр. Так, следующий пример class Test { public static void main(String args[]) { int bigNumber = 1234567890; float approximate = bigNumber; System.out.println(approximate); } } выведет на экран строку 1234567936. Это связано с тем, что при преобразовании int в float результирующее значение равно 1.2345679E9 из-за того, что мантисса чисел типа float вмещает только 8 десятичных цифр (здесь для правильной работы следует использовать преобразование к типу double). Тем не менее, исполняющая система никогда не генерирует ошибок при выполнении перечисленных преобразований. 5.4.1.2. Сужающие преобразования чиселСужающие преобразования чисел — это преобразования числового типа в "меньший" числовой тип, которые могут привести как к потере величины, так и к потере точности. Такими преобразованиями в Java являются:
Мы не будем здесь подробно рассматривать правила, по которым происходят эти преобразования, поскольку интуитивно они понятны, а формально достаточно громоздки. При их применении важно помнить, что Java, в отличие от других языков, не генерирует ошибок при переполнении (overflow) или потере значения (underflow), поэтому контроль за корректностью преобразований полностью ложится на программиста. 5.4.1.3. Расширяющие преобразования ссылокРасширяющие преобразования ссылок — это преобразования производных ссылочных типов в типы их предков, которые не требуют никаких действий на этапе исполнения и никогда не генерируют ошибок. Такими преобразованиями в Java являются:
5.4.1.4. Сужающие преобразования ссылокСужающие преобразования ссылок — это преобразования производных ссылочных типов в типы их потомков. Эти преобразования требуют проверки своей легитимности на этапе исполнения и могут генерировать исключение ClassCastException. Такими преобразованиями в Java являются:
5.4.1.5. Преобразования в строкиЛюбое выражение в Java, включая null, может быть преобразовано в тип String. 5.4.1.6. Недопустимые преобразованияСледующие преобразования типов в Java запрещены:
5.4.2. Контексты преобразований5.4.2.1. Преобразование при присваиванииПреобразование при присваивании происходит, когда значение выражения присваивается переменной. При этом тип выражения преобразуется к типу переменной. При присваивании всегда возможны расширяющие преобразования типов (как числовых, так и ссылочных). Сужающее преобразование возможно только при соблюдении следующих условий:
Например, оператор Если тип выражения не может быть преобразован к типу переменной, то компилятор генерирует ошибку. В остальных случаях мы говорим, что тип выражения совместим по присваиванию с типом переменной. Так, следующий фрагмент short s = 123; char c = s; // генерирует ошибку компиляции приведет к генерации ошибки, поскольку типы char и short несовместимы по присваиванию согласно данных выше определениям (первый реализован 16-битовыми словами без знака, а второй — со знаком). 5.4.2.2. Преобразование аргументов методаПреобразование аргументов метода происходит, когда фактические значения аргументов преобразуется к типу параметров метода или конструктора при его вызове. При этом всегда возможны расширяющие преобразования типов (как числовых, так и ссылочных) и недопустимы сужающие преобразования. Причины последнего запрета можно пояснить следующим примером: class Test { static int m(byte a, int b) { return a + b; } static int m(short a, short b) { return a - b; } public static void main(String args[]) { System.out.println(m(1, 2)); // генерирует ошибку компиляции } } Здесь класс Test содержит два одноименных метода, которые различаются только типами
параметров. Если бы сужающие преобразования аргументов были в Java разрешены, то исполняющей
системе пришлось бы определять, к какому из этих методов относится вызов 5.4.2.3. Преобразование в строкуПреобразование в строку происходит только в одном случае: когда бинарная операция + применяется к двум операндам, один из которых имеет тип String. В этой ситуации второй операнд также преобразуется к типу String, и результатом операции является конкатенация полученных строк. Подробнее этот процесс описан в гл. 5.14. 5.4.2.4. Явное преобразование типаЯвное преобразование типа происходит, когда к операнду явно применяется операция приведения типа (type cast). В этой ситуации могут применяться все описанные выше виды преобразований типов, кроме преобразования в строку. Попытка явного преобразования к типу, отмеченная выше, как запрещенная, вызовет ошибку компиляции. Кроме того, на этапе выполнения возможна генерация исключения ClassCastException, если заданное преобразование недопустимо. 5.4.3. Преобразования типов числовых операндовПреобразование типов в процессе вычисления числовых выражений имеет ряд особенностей. Они сводятся к двум случаям: преобразования операндов в унарных операциях и в бинарных операциях. Перед выполнением унарной операции:
Перед выполнением бинарной операции:
|
HIVE: All information for read only. Please respect copyright! |
Advertising: |
|
![]() ![]() |