JavaRush /Курси /Java Syntax Zero /Типи-обгортки детально

Типи-обгортки детально

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

1. Клас Integer

Integer крутий ще й тим, що це клас, а значить, у нього можуть бути поля і методи. І, звісно, вони у нього є. Навіть багато — кілька десятків. Тому ми розглянемо найосновніші з них.

У класу Integer є два поля, які містять максимальне і мінімальне значення типу int:

Поле Опис
Integer.MAX_VALUE
Максимальне значення типу int
Integer.MIN_VALUE
Мінімальне значення типу int

Іноді хочеться присвоїти змінній найменше або найбільше значення типу int. Щоб не перевантажувати код незрозумілими константами, можна дуже гарно написати:

Код Опис
int min = Integer.MIN_VALUE;
min буде дорівнювати 0x80000000

Також у класу Integer є кілька цікавих методів, ось вони:

Методи Опис
String Integer.toHexString(int)
Повертає рядок — шістнадцяткове представлення числа
String Integer.toBinaryString(int)
Повертає рядок — двійкове представлення числа
String Integer.toOctalString(int)
Повертає рядок — вісімкове представлення числа
Integer Integer.valueOf(int i)
Обгортає переданий int у Integer
Integer Integer.parseInt(String)
Повертає число, отримане з рядка

Раніше ви вже стикалися зі статичним методом Integer.parseInt(). Нагадаємо, як він працює:

int ім'я = Integer.parseInt(рядок);

Якщо в метод parseInt() передати рядок, що містить число (тільки цифри), він розпарсить цей рядок і поверне число, яке в ньому міститься.

Інші методи теж корисні. Наприклад, деякі з них можуть перетворювати передане число в рядок у двійковій, вісімковій або шістнадцятковій формі.



2. Клас Double

Клас Double, загалом, аналогічний класу Integer, тільки є обгорткою не для типу int, а для типу double. У нього також є цікаві для нас поля і методи, розглянемо деякі з них:

Цікавих полів у класу Double шість:

Поле Опис
double Double.NEGATIVE_INFINITY
Мінус нескінченність
double Double.POSITIVE_INFINITY
Плюс нескінченність
int Double.MIN_EXPONENT
Мінімальне значення експоненти (2x)
int Double.MAX_EXPONENT
Максимальне значення експоненти (2x)
double Double.MIN_VALUE
Мінімальне значення типу double
double Double.MAX_VALUE
Максимальне значення типу double

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

Якщо ти розділиш -1.0 на 0.0, отримаєш негативну нескінченність, якщо 1.0 на 0.0 — позитивну нескінченність. Тип double може не тільки ділити на нуль, але й зберігати такі значення.

Експонента числа double

З експонентою також усе просто. Число double всередині складається з мантиси і експоненти. Тільки ось значення експоненти — це не 10х, а 2х. Якщо експонента збільшиться на 1, остаточне значення числа стане більшим удвічі.

MIN_EXPONENT == -1024, у результаті отримуємо 2-1024 приблизно дорівнює 10-308

Також у класу Double є цікаві методи:

Методи Опис
String Double.toHexString(double)
Повертає рядок — шістнадцяткове представлення числа
boolean Double.isInfinite(double)
Перевіряє, чи є передане число нескінченністю.
boolean Double.isNaN(double)
Перевіряє, чи є передане число NaN
Double Double.valueOf(double)
Обгортає переданий double у Double
Double Double.parseDouble(String)
Повертає число, отримане з рядка

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

Аналогічно працює і метод isNaN() — перевіряє, чи є передане в нього число NaN: спеціальна константа, що позначає невизначеність (Not a Number, Не число).



3. Клас Character

Клас Character в першу чергу цікавий великою кількістю утилітних статичних методів, які дозволяють перевіряти символи на належність до різних категорій.

Приклади

Методи Опис
Character.isAlphabetic(int)
Перевіряє, чи є символ символом алфавіту
Character.isLetter(char)
Чи є символ буквою
Character.isDigit(char)
Чи є символ цифрою
Character.isSpaceChar(char)
Чи є символ пробілом, символом переносу рядка або зміни параграфа (коди: 12, 13, 14)
Character.isWhitespace(char)
Чи є символ роздільником: пробіл, tab і т.д.
Character.isLowerCase(char)
Символ у нижньому регістрі — малі літери?
Character.isUpperCase(char)
Символ у верхньому регістрі — великі літери?
Character.toLowerCase(char)
Перетворює символ у нижній регістр
Character.toUpperCase(char)
Перетворює символ у верхній регістр

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



4. Клас Boolean

Тип Boolean практично такий же, як тип boolean. Відмінності мінімальні.

Нижче ми покажемо спрощений варіант класу Boolean:

Код Опис
class Boolean
{
   public static final Boolean TRUE = new Boolean(true);
   public static final Boolean FALSE = new Boolean(false);

   private final boolean value;

   public Boolean(boolean value)
   {
      this.value = value;
   }

   public boolean booleanValue()
   {
      return value;
   }

   public static Boolean valueOf(boolean value)
   {
      return (value ? TRUE : FALSE);
   }
}


Константи: TRUE та FALSE


Змінна-значення

Конструктор класу Boolean




Метод повертає значення внутрішньої змінної-значення



Цей статичний метод вміє перетворювати true на TRUE і false на FALSE.

У типі Boolean є дві константи (два поля):

Константи класу Аналог типу boolean Опис
Boolean.TRUE
true
істина
Boolean.FALSE
false
хиба

Працювати з ними можна так само, як і з типом boolean:

Код Примітка
if (Boolean.TRUE)
{
}
Boolean — єдиний клас, який можна писати всередині умови
Boolean a = Boolean.TRUE;
boolean b = Boolean.TRUE;
boolean с = true;
Усі три змінні рівні true/TRUE
Boolean a = Boolean.TRUE;
Boolean b = Boolean.TRUE;
if (a == b)
Константи можна порівнювати і через equals, і через ==

Так теж буде працювати.

Autoboxing тут працює чудово, тому можете користуватися цим типом так само, як типом boolean: ніяких підводних каменів тут немає.

Як записано Як це працює
Boolean a = true;
Boolean b = true;
Boolean c = false;
boolean d = a;
Boolean a = Boolean.valueOf(true);
Boolean b = Boolean.valueOf(true);
Boolean c = Boolean.valueOf(false);
boolean d = a.booleanValue();

А ось як відбуваються порівняння між типами boolean та Boolean:

boolean a = true;
Boolean b = true; // буде дорівнювати Boolean.TRUE
Boolean c = true; // буде дорівнювати Boolean.TRUE

a == b; // true (порівнюються як примітиви за значенням)
a == c; // true (порівнюються як примітиви за значенням)
b == c; // true (порівнюються за посиланням, але вказують на той самий об'єкт)

Якщо дуже потрібно створити незалежний об'єкт Boolean, то треба створити його явно:

boolean a = true;
Boolean b = new Boolean(true); // новий об'єкт Boolean
Boolean c = true; // буде дорівнювати Boolean.TRUE

a == b; // true (порівнюються як примітиви за значенням)
a == c; // true (порівнюються як примітиви за значенням)
b == c; // false (порівнюються за посиланням, вказують на різні об'єкти)

І ще один приклад: використання Boolean всередині if:

Код Примітка
Boolean less = (2 < 3);
if (less)
{
   ...
}
Скомпілюється і буде працювати

Скомпілюється, але працювати не буде:

Код Примітка
Boolean less = null;
if (less)
{
   ...
}

Помилка. У цьому рядку кинеться виняток


5. Кешування значень при autoboxing

А ось із цілими типами-обгортками бувають підводні камені.

Як ти вже знаєш, якщо порівнюєш int і Integer, Integer перетворюється в int:

Як записано Як це працює
int a = 5;
Integer b = 5;
if (a == b)
{
   ...
}
int a = 5;
Integer b = Integer.valueOf(5);
if (a == b.intValue())
{
   ...
}

Якщо порівнювати між собою два об'єкти типу Integer, перетворення до типу int не буде:

Код Вивід на екран
Integer a = 500;
Integer b = 500;
int c = 500;

System.out.println(a == b); // порівняння посилань
System.out.println(a == c);
System.out.println(b == c);




false
true
true

Хоча a == c і b == c, але a != b, бо при порівнянні a і b порівнюються посилання. Що, в принципі, очікувано.

Сюрприз

Але, якщо ми замінимо 500 на 100, отримаємо зовсім інший результат:

Код Вивід на екран
Integer a = 100;
Integer b = 100;
int c = 100;

System.out.println(a == b); // порівняння посилань
System.out.println(a == c);
System.out.println(b == c);




true
true
true

Річ у тому, що при autoboxing не завжди створюється дійсно новий об'єкт Integer. Для значень від -128 до 127 включно об'єкти кешуються.

У класі Integer є прихований масив, який зберігає об'єкти: Integer(-128), Integer(-127), ... Integer(126), Integer(127)

Якщо ти напишеш Integer x = 128, autoboxing створить новий об'єкт, а якщо Integer x = 127, autoboxing візьме готовий об'єкт із кешу (із масиву).

Якщо не хочеш, щоб об'єкт Integer брався із кешу, доведеться створити його явно, написавши: Integer x = new Integer(127);

Такий кеш є у всіх типів-обгорток: Integer, Long, Byte, Short, Boolean. У типу Boolean обидва його значення TRUE і FALSE є константами: по суті теж кешуються.


Коментарі (22)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
Зоряна Блащук Рівень 23
15 вересня 2024
В останній задачі не зрозуміла, чому для порівняння > < ми теж не використовуємо charValue(). чи можна вважати що оператори >, <, >=, <= працюють тільки з примітивними типами в java автоматично проводить авторозпаковку?
Андрій Рівень 18
15 січня 2024
Затролили в задачі "Метод ділення" 😑
Гаркін Рівень 14
15 травня 2024
Я ржав. Написав 24 рядки коду. А потім переглянув скільки треба було... Ну і примітка від Idea

Complexity is 58 Bloody hell ...
🤣
12 травня 2023
"a == c і b == c, але a != b" - я на завод)
Yurii Kuzniak Рівень 30
27 травня 2023
Просто треба запам'ятати що неможна два Integer зрівнювати ==, а тільки .equals() Надіюсь що ти зрозумів :D
29 травня 2023
Дякую, я зрозумів. Це був просто жарт) До речі якщо їхні значення між -128 і 127 то виявляється можна і через == порівнювати upd: забув що про це якраз у цій лекції і пишуть
Yurii Kuzniak Рівень 30
19 червня 2023
Добре що жарт) на заводську зарплату ледь проживеш) та й Integer мені здається не дуже використовують
Oleksandr Tkachenko Рівень 51
17 квітня 2023
остання задача сипле купу помилок якщо її запустити але валідацію проходить)))
Val Рівень 30
18 лютого 2023
так, 3-ю задачку треба гуглити ))))
Владислав Рівень 26
17 лютого 2023
Третя задача неймовірно цікава, трохи погугливши знайшов такий метод вирішення
kalkulator¹ Рівень 51
10 листопада 2022
третя задача фейл ахахахахахахахах
kalkulator¹ Рівень 51
10 листопада 2022
о тепер зрозуміло стало як потрібно було робити 4 завдання hard декілька лекцій назад )
WhoAMI Рівень 51
12 жовтня 2022
усі завдання легенькі. а 3-тя доволі цікава. трохи подумати і використати toCharArray()
Anonymous #696530 Рівень 19
19 вересня 2022
У "Метод ділення" замахався набирати 3-метрові умови
Set Crowley Рівень 20
29 вересня 2022
Я теж... потім підглянув правильний розв'язок.... просто в методі треба а/б, та й усе. Жодних умов не потрібно
Taras Woytowitch Рівень 16
9 січня 2023
Я на всякий випадок замість a/b написав 1.0*a/b
13 березня 2025
на який "всякий"?) в параметрах метода прилітають тільки дабли, нема сенсу їх додатково приводити в дабл ше раз)