JavaRush /Курси /Java Syntax Zero /Примітивні типи в Java

Примітивні типи в Java

Java Syntax Zero
Рівень 8 , Лекція 1
Відкрита

1. Список примітивних типів

У Java є 8 базових примітивних типів. Примітивними їх називають тому, що значення цих типів не є об'єктами та зберігаються безпосередньо всередині змінних.

У цій таблиці наведено коротку інформацію про ці типи:

Тип Розмір,
байт
Діапазон значень Значення за замовчуванням Опис
byte 1 -128 .. 127 0 Найменше ціле — 1 байт
short 2 -32,768 .. 32,767 0 Коротке ціле, 2 байти
int 4 -2*109 .. 2*109 0 Ціле число, 4 байти
long 8 -9*1018 .. 9*1018 0L Довге ціле, 8 байтів
float 4 -1038 .. 1038 0.0f Дробове, 4 байти
double 8 -10308 .. 10308 0.0d Дробове подвійної довжини, 8 байтів
boolean 1 true, false false Логічний тип (тільки true і false)
char 2 0 .. 65,535 '\u0000' Символи, 2 байти, завжди більші за 0
Значення за замовчуванням

До речі, є важливий нюанс. Якщо оголосити змінну класу (поле класу) або статичну змінну класу, але не присвоїти їй жодного значення, вона ініціалізується значенням за замовчуванням. Перелік таких значень наведено в таблиці.

Локальні змінні методів не мають значень за замовчуванням, і якщо ви не присвоїли такій змінній жодного значення, вона вважається неініціалізованою, і використовувати її значення не можна.

Але повернімося до примітивних типів і розгляньмо їх докладніше.



2. Цілі типи

У мові Java є аж 4 цілих типи: byte, short, int і long. Вони відрізняються між собою за розміром і діапазоном значень, які можуть зберігати.

Тип int

Найчастіше використовується тип int. Його назва походить від Integer (цілий). Всі цілочислові літерали в коді мають тип int (якщо до числа не додано літеру L, F або D).

Змінні цього типу можуть мати значення від -2 147 483,648 до +2 147 483,647.

Це досить багато, вистачає майже на всі випадки. Майже всі функції, що повертають число, повертають саме число типу int.

Приклади:

Код Пояснення
int n = "Рядок".length();
Метод length() повертає довжину рядка.
String[] array = {"Tik", "Tak", "Toe"};
int n = array.length;
Поле length містить довжину масиву.

Тип short

Тип short отримав свою назву від short int. Його ще називають коротке ціле. На відміну від типу int, його довжина всього два байти, а можливий діапазон значень — від -32768 до +32767.

Тобто в ньому навіть число мільйон не збережеш. Навіть 50 тисяч. Цей цілочисловий тип використовується в Java рідше за всіх. Його використовують, головним чином, тоді, коли хочуть заощадити пам'ять.

Припустімо, вам заздалегідь відомо, що значення, з якими ви працюєте, не перевищують 30 тисяч, і таких значень мільйони.

Наприклад, ви пишете програму, яка обробляє зображення надвисокої чіткості: на один колір припадає 10 біт. А точок у вашому зображенні — мільйон. Отут таки має значення, який тип використовувати — int чи short.

Тип long

Цей тип отримав свою назву від long int — його ще називають довге ціле. На відміну від типу int, у нього просто гігантський діапазон значень: від -9*1018 до +9*1018.

Чому ж він не є основним цілим типом?

Річ у тім, що мова Java з'явилася ще в середині 90-х, коли більшість комп'ютерів були 32-розрядними. А це означало, що всі процесори були налаштовані на роботу з числами довжиною 32 біти. З цілими числами довжиною 64 біти процесори вже вміли працювати, але операції з ними виконувалися повільніше.

Отож програмісти розумно вирішили зробити стандартним цілим типом тип int, ну а тип long використовувати лише тоді, коли без нього дійсно не обійтися.

Тип byte

Це найменший цілочисловий тип у Java, але його досить часто використовують. Його назва збігається зі словом byte — мінімальною адресованою коміркою пам'яті в Java.

Діапазон допустимих значень типу byte не дуже великий: від -128 до +127. Проте його сила не в цьому. Тип byte найчастіше використовується тоді, коли потрібно зберігати в пам'яті великий блок знеособлених даних. Масив типу byte просто ідеально підходить для таких цілей.

Наприклад, вам потрібно кудись скопіювати файл.

Вам не потрібно обробляти вміст файлу: ви просто хочете створити область пам'яті (буфер), скопіювати в неї вміст файлу, а потім записати ці дані з буфера в інший файл. Масив типу byte — саме те, що для цього потрібно.

Тим більше, що в змінній-масиві зберігається тільки посилання на область пам'яті. Коли значення цієї змінної потрібно передати до якогось методу, передається тільки її адреса в пам'яті, а сам блок пам'яті не копіюється.

byte[] buffer = new byte[1024*1024];
FileInputStream sourceFile = new FileInputStream("c:\\data.txt");
FileOutputStream destFile = new FileOutputStream("c:\\output.txt");
while (true)
{
   int size = sourceFile.read(buffer);   // читаємо дані з файлу в буфер
   destFile.write(buffer, 0, size);      // записуємо дані з буфера у файл

   // припиняємо копіювання, якщо буфер заповнено не до кінця
   if (size < buffer.length) break;
}
sourceFile.close();
destFile.close();


3. Дійсні типи

Серед примітивних типів також є два дійсних. Проте це не зовсім точна назва. Офіційно вони називаються числами з рухомою крапкоюfloating point numbers. Назва походить зі стандарту, де роздільником цілої та дробової частин визначено крапку (не кому).

Корисно

У кожній країні свої стандарти запису чисел (а ви й не знали!).

Дехто звик використовувати точку як роздільник груп розрядів, а кому — для відділення дробової частини: наприклад, мільйон цілих і 153 тисячних можна записати як 1.000.000,153. А от у США, де мешкали творці Java, діє інший стандарт: 1,000,000.153

У мові Java є два примітивних типи з рухомою крапкою: double і float.

Як ми вже казали, ці типи всередині влаштовані особливим чином: фактично кожна змінна цих типів — це не одне число, а два.

Наприклад, дробове число 987654.321 можна представити як 0.987654321*106. Тому в пам'яті воно буде представлене як два числа 987654321 (мантиса — значуща частина числа) і 6 (експонента — степінь десяти).

Тип float

Назва типу float походить від терміна floating point number. Розмір цього типу зовсім невеликий — всього 4 байти (32 біти), але він може зберігати значення від -3.4*1038 до 3.4*1038. Мантиса займає 24 біти, а експонента — 8 бітів. Цей тип здатний зберігати всього 8 значущих цифр.

Такий підхід дає змогу зберігати набагато більші числа, ніж int, використовуючи ті самі 4 байти. Натомість ми жертвуємо точністю. Частина пам'яті витрачається на зберігання мантиси, тому такі числа зберігають лише 6-7 знаків після десяткової коми, інші знаки відкидаються.

Приклад:

Код Значення змінної
float a = (float) 123.456789;
123.45679
float a = (float) 12345.9999;
12346.0
float a = (float) -123.456789E-2;
-1.2345679

Як бачите, основний недолік цього типу — дуже мала кількість значущих цифр і втрата точності вже у восьмій цифрі. Тому тип float не користується особливою популярністю серед Java-програмістів.

Тип double

Тип double — це стандартний тип чисел із рухомою крапкою. Його назва походить від double floating point. Його також називають числом із рухомою крапкою подвійної точності. Усі дійсні літерали за замовчуванням мають тип double.

Цей тип займає 8 байтів пам'яті (64 біти) і може зберігати значення від -1.7*10308 до 1.7*10308. Важливий момент: його мантиса займає 53 біти, а решту 11 біт — експонента.

Це дає змогу зберігати 15–17 значущих цифр.

Приклад:

Код Значення змінної
double a = 1234567890.1234567890;
1234567890.1234567
double a = 1234567890.1234512345;
1234567890.1234512
double a = 1234567890.1357913579;
1234567890.1357913

Така точність, особливо як порівняти з типом float, є визначальною: 99 % усіх операцій із дійсними числами виконуються з типом double.

Для експоненти виділяється 11 бітів, що дає змогу зберігати степінь десяти від -323 до +308 (степінь числа два — від -1024 до +1023). Тип double може легко зберігати числа із сотнею нулів після десяткової коми.

Код Значення змінної
double a = 2E-300 * 3E+302
600.0


4. Нескінченність

Числа з рухомою крапкою мають ще одну цікаву особливість: вони дозволяють зберігати спеціальне значення, яке позначає нескінченність. Причому існують як додатна нескінченність, так і від'ємна нескінченність.

Приклади:

Код Примітка
System.out.println( 100.0 / 0.0 );
Infinity
System.out.println( -100.0 / 0.0 );
-Infinity
double a = 1d / 0d;
double b = a * 10;
double c = b - 100;
a == Infinity
b == Infinity
c == Infinity

Якщо нескінченність помножити на число, отримаємо нескінченність. Якщо до нескінченності додати число, отримаємо нескінченність. Дуже зручно.

Не число (NaN)

Результатом будь-яких операцій із нескінченністю буде нескінченність. Здебільшого — так. Але не завжди.

Числа з рухомою крапкою можуть зберігати ще одне спеціальне значення — NaN. Це є скороченням від Not a Number (не число).

У математиці, якщо поділити нескінченність на нескінченність, виникає невизначеність.

Проте в мові Java результатом ділення нескінченності на нескінченність буде NaN.

Приклади:

Код Примітка
System.out.println(0.0 / 0.0);
NaN
double infinity = 1d / 0d;
System.out.println(infinity / infinity);

NaN
double a = 0.0 / 0.0;
double b = a * 10;
double c = b - 100;
double d = a + infinity;
a == NaN
b == NaN
c == NaN
d == NaN

Результатом будь-якої операції з NaN буде NaN.



5. Тип char

Серед примітивних типів у Java є ще один, вартий особливої уваги, — тип char. Його назва походить від слова Character, а сам тип використовується для зберігання символів.

А символи — це саме те, з чого складаються рядки: кожен рядок є масивом символів.

Проте ще цікавіше, що тип char — це водночас числовий тип! Так би мовити, тип подвійного призначення.

Річ у тім, що насправді тип char зберігає не символи, а коди символів у кодуванні Unicode. Кожному символу відповідає число — числовий код символу.

Кожна змінна типу char займає в пам'яті два байти (так само, як і тип short). Однак на відміну від типу short, цілочисловий тип char — беззнаковий і може зберігати значення від 0 до 65535.

Тип char — це гібридний тип. Його значення можна інтерпретувати і як числа (їх можна складати й множити), і як символи. Так зробили через те, що, хоча символи й мають візуальне подання, для комп'ютера вони насамперед просто числа. І працювати з ними як з числами значно зручніше.

Unicode

Unicode — це спеціальна таблиця (кодування), в якій містяться всі символи світу. І кожен символ має свій номер. Ось ця таблиця (приблизний вигляд):

Примітивні типи в Java

Присвоїти значення змінній типу char можна різними способами.

Код Опис
char a = 'A';
Змінна а міститиме латинську літеру А.
char a = 65;
Змінна а міститиме латинську літеру А. Її код саме 65.
char a = 0x41;
Змінна а міститиме латинську літеру А.
Її код саме 65, що відповідає коду 41 у шістнадцятковій системі.
char a = 0x0041;
Змінна а міститиме латинську літеру А.
Її код саме 65, що відповідає коду 41 у шістнадцятковій системі.
Два зайві нулі не змінюють значення.
char a = '\u0041';
Змінна а міститиме латинську літеру А.
Ще один спосіб задати символ за допомогою його коду.

Найчастіше символ просто вказують у лапках (як у першому рядку таблиці). Проте останній спосіб теж досить поширений. Він має ту перевагу, що його можна використовувати в рядках.

І як вже було сказано, тип char — це водночас цілочисловий тип, тому можна використовувати такий запис:

Код Виведення на екран
char a = 'A';
a++;
System.out.println(a);
На екран буде виведено латинську літеру В. Тому що:
A65
B66
C67

Робота з типом char

Кожний символ char — це насамперед число (код символу), а потім уже символ. Якщо знати код символу, його завжди можна отримати в програмі. Приклад:

Код Виведення на екран
char c = (char) 1128;
System.out.println(c);

Ѩ

Стандартні коди

У цій таблиці наведено найвідоміші коди символів:

Символи Коди
0, 1, 2, ... 9 48, 49, 50, ... 57
a, b, c, ... z 97, 98, 99, ... 122
A, B, C, ... Z 65, 66, 67, ... 90


6. Тип boolean

І останній примітивний тип — це boolean.

Як ви вже знаєте, він може набувати лише двох значень: true і false.

Власне, ви вже знаєте про цей тип усе, що можна.

Коментарі (21)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
IronMan57 Рівень 27
26 листопада 2024
Хтось знає, як за допомогою данних типу char вивести на екран українські букви 'І', 'і', 'Ґ', 'ґ'? З буквами 'Є' та 'Ї' ніяких проблем немає. Вони мають в Юнікод в шістнадцятиричній системі коди 404 та 407, і нормально виводяться на екран. А от при спробі вивести на екран букви 'і' та 'ґ', хоча вони і є в таблиці Юнікод під шістнадцятиричними кодами 456 та 491 відповідно, я отримав символи '?'. Наскільки, я зрозумів, це означає, що система не може відобразити відповідний символ.
Jaroslav Рівень 48
27 листопада 2024

char aChar = 'ї';
System.out.println(aChar);
нормально виводить 'і' та 'ї' Подивись в налаштуваннях який всталовлено шрифт. В мене JetBrains Mono
IronMan57 Рівень 27
26 листопада 2024
Одне, як мені здається, цікаве спостереження. При виконанні вправ про найменші цілі числа спробував задавати їх як добутки, поскільки це завжди якісь степені двійки. Наприклад, найменший int: int k = -1024 * 1024 * 1024 * 2; чи найменший short: short j = -32 * 1024; І такий підхід спрацьовував, та приймався системою за правильну відповідь. Але з типом long такий фокус не пройшов. Задавши long smallestLong = -1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 8; після виводу цього числа на екран отримав число -1. Причиною, як виявилось було те, що коли в коді ціле число задається саме у виді числа (1; 1024; 32768), то за замовчуванням воно має тип int. Перемноживши кілька разів 1024 саме на себе, ми виходимо за межі діапазону доступного для типу int, і замість великого цілого числа отримуємо -1. Але через добуток також можна отримати велике ціле число, вказавши явно, що воно має бути не типу int, а типу long. Зробити це можна додавши хоча б до одного з множників букву L. Ось таким чином: long smallestLong = -1024L * 1024 * 1024 * 1024 * 1024 * 1024 * 8; Майте на увазі, що в результаті операцій додавання, чи множення позитивних чисел, можна в наслідку переповнення отримати негативний результат.
Jaroslav Рівень 48
27 листопада 2024
Але з типом long такий фокус не пройшов. Задавши long smallestLong = -1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 8; Бо всі введені числа int і переповнення сталося задовго до максимального long Спробуй так:

System.out.println(-1024l * 1024 * 1024 * 1024 * 1024 * 1024 * 8);
bogdan kravchuk Рівень 11
9 березня 2023
вже пішов 2 місяць мого навчання) а точніше місяць і тиждень. по 2 години в день😅 в суботу неділю 3. А ти скільки навчаєшся?😉
Valerii Рівень 33 Expert
23 квітня 2023
Хай друже,як далі навчання)?
Ва Дим Рівень 28
20 березня 2024
йду все занов.Перший раз дібрався до 25 рівня .Тепер повторюю і збираюсь вже вище.На багато вище
Dmytro Рівень 26
23 червня 2024
Учеба закончилась?)
kivi Рівень 20
26 січня 2023
в останній задачі достатньо запустити код який дає джавараш, і через output зрозуміло який символ в якій змінній
Anonymous #696530 Рівень 19
27 липня 2022
Дещо пригальмував на експонентах, а так завдання в цій лекції легкі. По char задача найцікавіша.
Roma Chernesh Рівень 16
19 грудня 2022
Мені навпаки найбільш зайшла задача про ексоненти. Так мозок не міг вкумекати, що це за така Мантиса така. Але як гарно погуглив, то все стало зрозуміло:)
Viacheslav B. Рівень 1
5 лютого 2024
також прийшлося гугллити , схоже що я пропустив це у школьной программе ) але поки що задачу не вирішив ( спробую повернутися пізніше
Anonymous #3107519 Рівень 10
20 липня 2022
Я також
Александр Рівень 12
2 листопада 2021
я все еще учусь)
Taras Woytowitch Рівень 16
4 січня 2022
і я
Ольга Рівень 33
11 лютого 2022
и я
Anonymous #3026165 Рівень 11
8 червня 2022
И я)
Ира Оксак Рівень 11
15 серпня 2022
и я))
Oleksii Pliukhin Рівень 13
21 січня 2023
и я
Nicky^^ Рівень 32
1 лютого 2023
І я
Женя Иващенко Рівень 32
22 лютого 2023
І я)