Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
3 - Лексические структуры языка. Типы данных. И...docx
Скачиваний:
9
Добавлен:
19.11.2019
Размер:
93.32 Кб
Скачать

4.8 Приоритет операций

Операции в выражениях выполняются слева направо, однако, в соответствии со своим приоритетом. Так операции умножения в выражении

y = x + z * 5;

будет выполнена раньше, чем операция сложения, поскольку приоритет операции умножения выше, чем приоритет операции сложения.

Приоритеты операций (в порядке уменьшения приоритета) в Java приведены в табл. 2.1.4.

Таблица 2.1.4. Приоритеты операций в Java

Операция

Описание

() [ ]

Круглые и квадратные скобки

++ -- + - ~ !

Декремент, инкремент, унарный плюс, унарный минус, поразрядное отрицание, логическое отрицание

* / %

Умножение, деление, деление нацело

+ -

Сложение, вычитание

>> >>> <<

Побитовый сдвиг вправо, побитовый сдвиг вправо с заполнением старшего бита нулем, побитовый сдвиг влево

> >= < <=

Сравнение на больше, больше или равно, меньше, меньше или равно

== !=

Сравнение на равенство, сравнение на неравенство

&

Поразрядное и логическое И

^

Поразрядное и логическое исключающее ИЛИ

|

Поразрядное и логическое ИЛИ

&&

Логическое укороченное И

||

Логическое укороченное ИЛИ

? :

Условная операция

=op

Комбинированные операции (op – одна из арифметических или побитовых операций)

Круглые скобки повышают старшинство операций, которые находятся внутри них. Так, если в приведенное выше выражение вставить скобки:

y = (x + z) * 5;

то сначала будет выполнена операция сложения, а затем операция умножения.

Иногда скобки используют просто для того, чтобы сделать выражение более читабельным, например:

(x > 1) && (x <= 5)

4.9 Преобразование и приведение типов при выполнении операций

В операции присваивания и арифметических выражениях могут использоваться литералы, переменные и выражения разных типов, например:

byte x;

double y = x + 5;

В этом примере выполняется операция сложения переменной x типа byte и литерала 5 (типа int) и результат присваивается переменной y типа double.

В Java, как и в языке C, преобразования типов при вычислении выражений могут выполняться автоматически, либо с помощью оператора приведения типа. Однако правила приведения типов несколько отличаются от правил языка C, и в целом являются более строгими, чем в языке C.

При выполнении операции присваивания преобразование типов происходит автоматически, если происходит расширяющее преобразование (widening conversion) и два типа совместимы.

Расширяющими преобразованиями являются преобразования byte®short®int®long®float®double.

Для расширяющих преобразований числовые типы, включая целый и с плавающей точкой, являются совместимыми друг с другом. Однако числовые типы не совместимы с типами char и boolean. Типы char и boolean не совместимы также и друг с другом.

В языке Java выполняется автоматическое преобразование типов также и при сохранении литеральной целочисленной константы (которая имеет по умолчанию тип int) в переменных типа byte, short или long (однако если литерал имеет значение вне диапазона допустимых значений для данного типа, выдается сообщение об ошибке: возможная потеря точности).

Если преобразование является сужающим (narrowing conversion), т. е. выполняется преобразование byte¬short¬char¬int¬long¬float¬double, то такое преобразование может привести к потере точности числа или к его искажению. Поэтому при сужающих преобразованиях при компиляции программы выводится диагностическое сообщение о несовместимости типов и файлы классов не создаются. Такое сообщение будет выдано и при попытке преобразование выражений типа byte или short в переменную типа char.

Если все же необходимо выполнить такие преобразования, используется операция приведения (cast) типа, которая имеет следующий формат:

(тип-преобразования) значение

где тип-преобразования определяет тип, в который необходимо преобразовать заданное значение, например, в результате выполнения операторов:

byte x = 71;

char symbol = (char) x;

переменная symbol получит значение 'G'.

Если значение с плавающей точкой присваивается целому типу, то (если значение с плавающей точкой имеет дробную часть) при явном преобразовании типа происходит также усечение (truncation) числа. Так, в результате выполнения оператора

int x = (int) 77.85;

переменная x получит значение 77. Если же присваиваемое значение лежит вне диапазона типа-преобразования, то результатом преобразования будет остаток от деления значения на модуль диапазона присваиваемого типа (для чисел типа byte модуль диапазона будет равен 256, для short – 65536, для int – 4294967296 и для long – 18446744073709551616). Например, в результате выполнения оператора

byte x = (byte) 514;

переменная x получит значение 2.

При преобразовании целых или вещественных чисел в данные типа char, преобразование в символ происходит, если исходное число лежит в диапазоне от 0 до 127, иначе символ получает значение '?'.

При выполнении арифметических и побитовых преобразований все значения byte и short, а также char расширяются до int, (при этом в вычислениях для char используется числовое значение кода символа) затем, если хотя бы один операнд имеет тип long, тип целого выражения расширяется до long. Если один из операндов имеет тип float, то тип полного выражения расширяется до float, а если один из операндов имеет тип double, то тип результата будет double. Так, если объявлены переменные

byte a, c;

short b;

то в выражении

a + b * c – 15L + 1.5F + 1.08 - 10;

сначала, перед вычислением a + b * c значения переменных будут расширены до int, затем, поскольку константа 15 имеет тип long, перед вычитанием результат вычисления будет увеличен до long. После этого, поскольку литерал 1.5 имеет тип float перед сложением с этим литералом результат вычисления a + b * c – 15L будет расширен до float. Перед выполнением сложения с числом 1.08 результат предыдущих вычислений будет расширен до double (поскольку вещественные константы по умолчанию имеют тип double) и, наконец, перед выполнением последнего сложения литерал 10 (по умолчанию int) будет расширен до double. Таким образом, результат вычисления выражения будет иметь тип double.

Автоматические расширения типов (особенно расширения short и byte до int) могут вызывать плохо распознаваемые ошибки во время компиляции. Например, в операторах:

byte x = 30, y =5;

x = x + y;

перед выполнением умножения значение переменных x и y будет расширено до int, а затем при выполнении попытки присвоения результата вычисления типа int переменной типа byte будет выдано сообщение об ошибке.

Чтобы этого избежать надо использовать во втором операторе явное преобразование типов:

x = (byte) (x + y);

Выражение x + y необходимо заключит в скобки потому, что приоритет операции приведения типа, заключенной в скобки, выше, чем приоритет операции сложения. Кстати, если записать второй оператор в виде:

x += y;

то сообщения об ошибке не будет.