Більшість операцій над примітивними типами виконується не за допомогою методів, а за допомогою спеціальних символів, які називаються знаком операції .
Операція присвоєння
Присвоєння змінної значення константи, іншої змінної або виразу (змінних та/або констант, розділених знаками операцій), називається операцією присвоєння та позначається знаком " = ", наприклад:x = 3; y = x; z = x;
У Java допустимо багаторазове використання операції присвоєння в одному виразі, наприклад:
x1 = x2 = x3 = 0;
Ця операція виконується праворуч наліво, тобто. спочатку змінної x3
присвоюється значення 0
, потім змінної x2
присвоюється значення змінної x3
( 0
), і, нарешті, змінної x1
присвоюється значення змінної x2
( 0
). Знаки операцій, аргументами яких є числа, поділяються на дві категорії: унарні знаки операцій з одним аргументом і бінарні з двома аргументами.
Унарні операції
У Java визначено такіунарные операции
:- унарний мінус "
-
" - змінює знак числа чи висловлювання на протилежний; - унарний плюс "
+
" - не виконує жодних дій над числом чи виразом; - побітове доповнення "
~
" (лише цілих) – інвертує все біти поля числа (змінює 0 на 1 і 1 на 0); - инкремент "
++
" (лише цілих) – збільшує значення змінної на 1; - декремент "
--
" (лише цілих) – зменшує значення змінної на 1.
+
" і "
-
" :
int i = 3, j, k;
j= -i; // j = -3
k = +i; // k = 3
Приклад операції побітового доповнення:
int a = 15;
int b;
b = ~a; // b = -16
Числа
a
є
b
числами типу
int
, тобто. представляються всередині комп'ютера як двійкові цілі числа зі знаком довжиною 32 біта, тому двійкове уявлення чисел
a
виглядатиме
b
так:
a = 00000000 00000000 00000000 00001111
b = 11111111 11111111 11111111 11110000
Як видно з цього уявлення, всі нульові біти в числі a змінені на поодинокі біти в числі
b
, а поодинокі біти в a змінені на нульові біти. Десятичним поданням числа
b
буде
–16
. Знаки операції інкременту та декременту можуть розміщуватися як до, так і після змінної. Ці варіанти називаються відповідно
префіксною та
постфіксною записом цих операцій. Знак операції у префіксному записі повертає значення свого операнда
після обчислення виразу. При постфіксному записі знак операції
спочатку повертає значення свого операнда і лише після цього обчислює інкремент чи декремент, наприклад:
int x = 1, y, z;
y = ++x;
z=x++;
Змінна
y
буде присвоєно значення
2
, оскільки спочатку значення
x
буде збільшено на
1
, а потім результат буде надано змінної
y
. Змінною
z
буде присвоєно значення
1
, оскільки спочатку змінної
z
буде надано значення, а потім значення
x
буде збільшено на
1
. В обох випадках нове значення змінної
x
дорівнюватиме
2
. Слід зазначити, що в Java, на відміну від мови C, операції декременту та інкременту можуть застосовуватися і до речових змінних (типу
float
та
double
).
Бінарні знаки операцій поділяються на операції з числовим результатом та операції порівняння, результатом яких є булевське значення.
Арифметичні бінарні операції
У Java визначені наступні арифметичні бінарні операції :- додавання "
+
"; - віднімання "
-
"; - множення "
*
"; - розподіл "
/
"; - обчислення залишку від розподілу цілих чисел "
%
" (повертає залишок від розподілу першого числа на друге, причому результат матиме той самий знак, що й ділене), наприклад, результат операції5%3
дорівнюватиме2
, а результат операції (-7)%(-4) дорівнюватиме-3
. Java операція може використовуватися і для речових змінних (типуfloat
абоdouble
).
int x = 7, x1, x2, x3, x4, x5;
x1 = x +10; // x1 = 17
x2 = x – 8; // x2 = -1
x3 = x2 * x; // x3 = -7
x4 = x/4; // x4 = 1 (при делении целых чисел
// дробная часть отбрасывается)
x5 = x%4 // x5 = 3 (остаток от деления
// 7 на 4)
Побітові операції
Побитовые операции
розглядають вихідні числові значення поля бітів і виконують з них такі действия:- установка біта в i -ої позиції поля результату
1
, якщо обидва біта в i -их позиціях операндів рівні1
, або в0
іншому випадку –побитовое И
("&
"); - установка біта в i -ой позиції поля результату
1
, якщо хоча б один біт в i -их позиціях операндів дорівнює1
, або в0
іншому випадку -побитовое ИЛИ
("|
"); - установка біта в i -ої позиції поля результату
1
, якщо біти в i -их позиціях операндів не рівні один одному, або в0
іншому випадку -побитовое исключающее ИЛИ
("^
"); - зсув ліворуч бітів поля першого операнда на кількість бітів, що визначається другим операндом (біт знака числа при цьому не змінюється) -
побитовый сдвиг влево с учетом знака
"<<
"; - зсув вправо бітів поля першого операнда на кількість бітів, що визначається другим операндом (біт знака числа при цьому не змінюється) -
побитовый сдвиг вправо с учетом знака
">>
"; - зсув вправо бітів поля першого операнда на кількість бітів, що визначається другим операндом (біт знака числа при цьому також зсувається) -
побитовый сдвиг вправо без учета знака
">>>
".
-
Побітове І
int x = 112; // x: 00000000 00000000 00000000 01110000 int y = 94; // y: 00000000 00000000 00000000 01011110 int z; z = x & y; // z=80: 00000000 00000000 00000000 01010000
-
Побітове АБО
int x = 112; // x: 00000000 00000000 00000000 01110000 int y = 94; // y: 00000000 00000000 00000000 01011110 int z; z =x | y; // z = 126: 00000000 00000000 00000000 01111110
-
Побітове виключне АБО
int x = 112; // x: 00000000 00000000 00000000 01110000 int y = 94; // y: 00000000 00000000 00000000 01011110 int z; z =x ^ y; // z = 46: 00000000 00000000 00000000 00101110
-
Зсув вліво з урахуванням знаку
int x = 31, z; // x: 00000000 00000000 00000000 00011111 z = x << 2; // z = 124: 00000000 00000000 00000000 01111100
-
Зсув праворуч з урахуванням знака
int x = -17, z; // x: 11111111 11111111 11111111 11101111 z = x >> 2; // z = -5: 11111111 11111111 11111111 11111011
-
Зсув праворуч без урахування знака
int x = -17, z; // x: 11111111 11111111 11111111 11101111 z = x >>> 2; // z = 1073741819 // z: 00111111 11111111 11111111 11111011
Комбіновані операції
У Java для бінарних арифметичних операцій можна використовувати комбіновані (складові) знаки операцій:идентификатор операция = выражение
Це еквівалентно наступній операції:
идентификатор = идентификатор операция выражение
Приклади:
- Вираз
x += b
означаєx = x + b
. - Вираз
x -= b
означаєx = x - b
. - Вираз
x *= b
означаєx = x * b
. - Вираз
x /= b
означаєx = x / b
. - Вираз
x %= b
означаєx = x % b
. - Вираз
x &= b
означаєx = x & b
. - Вираз
x |= b
означаєx = x | b
. - Вираз
x ^= b
означаєx = x ^ b
. - Вираз
x <<= b
означаєx = x << b
. - Вираз
x >>= b
означаєx = x >> b
. - Вираз
x >>>= b
означаєx = x >>> b
.
Операції порівняння
У Java визначено такі операції порівняння:- "
==
" (рівно), "!=
" (не рівно), - "
>
" (більше), ">=
" (більше чи одно), - "
<
" (менше) "<=
" (менше чи одно)
=
" при порівнянні двох величин або викликає помилку при компіляції, або призводить до неправильного результату.
Приклади операцій порівняння:
boolean isEqual, isNonEqual, isGreater,
isGreaterOrEqual, isLess, isLessOrEqual;
int x1 = 5, x2 = 5, x3 = 3, x4 = 7;
isEqual = x1 == x2; // isEqual = true
isNonEqual = x1 != x2; // isNonEqual = false
isGreater = x1 > x3; // isGreater = true
// isGreaterOrEqual = true
isGreaterOrEqual = x2 >= x3;
isLess = x3 < x1; // isLess = true
isLessOrEqual = x1 <= x3; // isLessOrEqual = false
Булівські операції
Булевські операції виконуються над булевськими змінними та їх результатом також є значення типу boolean . У Java визначено такі булевські операції:- заперечення
"!"
– замінаfalse
наtrue
, чи навпаки; - операція
И
"&"
– результат дорівнюєtrue
, тільки якщо обидва операнда рівніtrue
, інакше результат –false
; - операція
ИЛИ
"|
" - результат дорівнюєtrue
, тільки, якщо хоча б один з операндів дорівнюєtrue
, інакше результат -false
. - операція що виключає
ИЛИ
"^
" – результат дорівнюєtrue
, тільки якщо операнди не рівні один одному, інакше результат –false
.
&
", "
|
" і "
^
" можна, як і відповідні побітові операції використовувати у складових операціях присвоювання: "
&=
" , "
|=
" і "
^=
" Крім того, до булевским операндам застосовні операції "
==
" (і) і "
!=
" ). Як видно з визначення операцій АБО і І, операція АБО призводить до результату
true
коли перший операнд дорівнює
true
незалежно від значення другого операнда, а операція І призводить до результату
false
коли перший операнд дорівнює
false
незалежно від значення другого операнда. У Java визначено ще дві булевські операції: другі версії булевських операцій І та АБО, відомі як укорочені (short-circuit) логічні операції:
&&
||
При використанні цих операцій другий операнд взагалі не буде обчислюватися, що корисно в тих випадках, коли правильне функціонування правого операнда залежить від того, чи має лівий операнд
значення
true
або
false
.
boolean isInRange, isValid, isNotValid,
isEqual, isNotEqual;
int x = 8;
isInRange = x > 0 && x < 5; // isInRange = false
isValid = x > 0 || x > 5; // isValid = true
isNotValid = !isValid; // isNotValid = false
isEqual = isInRange == isValid; // isEqual = false
// isNotEqual = true
isNotEqual = isInRange != isValid
Умовна операція
Умовна операція записується у формівыражение-1?выражение-2:выражение-3
. У цьому спочатку обчислюється вираз
выражение-1
, що має дати булевское значення, та був, якщо
выражение-1
має значення
true
, обчислюється і повертається
выражение-2
як результат виконання операції, чи (якщо
выражение-1
має значення
false
), обчислюється і, як результат виконання операції, повертається
выражение-3
.
Приклад умовної операції:
x=n>1?0:1;
Змінної x буде надано значення
0
, якщо
n>1
(вираз
n>1
має значення
true
) або
1
, якщо
n≤1
(вираз
n>1
має значення
false
).
Старшинство операцій
Операції у виразах виконуються зліва направо, проте, відповідно до свого пріоритету. Так операції множення у виразіy = x +z*5;
буде виконано раніше, ніж операція додавання, оскільки пріоритет операції множення вище, ніж пріоритет операції додавання. Пріоритети операцій (у порядку зменшення пріоритету) Java наведені в табл. 1.
Круглі дужки підвищують старшинство операцій, що усередині них. Так, якщо в наведеному вище виразі вставити дужки:
y = (x +z)*5;
то спочатку буде виконано операцію додавання, а потім операцію множення. Іноді дужки використовують просто для того, щоб зробити вираз більш читаним, наприклад:
(x > 1) && (x <= 5);
Перетворення та приведення типів при виконанні операцій
В операції присвоєння та арифметичних виразах можуть використовуватися літерали, змінні та вирази різних типів, наприклад:double y;
byte x;
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;
то повідомлення про помилку не буде.
Посилання на першоджерело: Операції над примітивними типами Java