JavaRush /Курси /Java Syntax Zero /Виведення типів Java-компілятором

Виведення типів Java-компілятором

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

1. Синтаксичний цукор

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

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

Розробники мови зробили все, щоб усунути із Java всю можливу надлишковість. Якщо в С++ можна щось зробити десятьма способами, то в Java те саме можна зробити переважно лише одним.

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

Ви, до речі, вже познайомилися з однією річчю, яку можна віднести до синтаксичного цукру, — це autoboxing і unboxing. Порівняйте:

Довгий код Компактний код
Integer a = new Integer(5);
int b = a.intValue();
Integer a = 5;
int b = a;
int b = 5;
Integer c = new Integer(b);
int b = 5;
Integer c = b;
Integer a = new Integer(1);
int b = 1;
if (a.intValue() == b)
{
   ...
}
Integer a = 1;
int b = 1;
if (a == b)
{
   ...
}

Замість довгого коду, як ліворуч, ви можете писати компактніший код, як праворуч. А розумний Java-компілятор на основі короткого коду сам згенерує його повну версію. Це і є синтаксичний цукор.


2. Виведення типу змінної – var

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

var ім'я = значення;

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

Приклади:

Як цей код бачимо ми Що бачить компілятор
var i = 1;
int i = 1;
var s = "Привіт";
String s = "Привіт";
var console = new Scanner(System.in);
Scanner console = new Scanner(System.in);
var list = new ArrayList<String>();
ArrayList<String> list = new ArrayList<String>();
var data = new int[]{1, 2, 3};
int[] data = new int[]{1, 2, 3};

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

Чимало списів було зламано в суперечках програмістів щодо того, чи варто додавати таку можливість у мову. Багато хто побоювався, що використанням var почнуть зловживати і прочитність коду сильно погіршиться.

Частка правди в цьому є, отож найкраще використовувати var там, де це підвищує прочитність коду. Наприклад, у цих двох випадках:

Випадок 1: значення змінної чітко вказує на її тип

Код Пояснення
var stream = url.getInputStream();
Змінна має тип InputStream
var name = person.getFullName();
Змінна має тип String

А от у цих випадках використовувати var не варто. Нумо скажіть, який тип має змінна?

Код Пояснення
var result = task.execute();
Тип змінної визначити важко
var status = person.getStatus();
Тип змінної визначити важко

Випадок 2: тип змінної не є важливим для розуміння коду

Часто в коді трапляються ситуації, коли для змінної не викликаються ніякі методи — вона просто використовується для тимчасового зберігання якихось даних. Використання var тут абсолютно не погіршує розуміння коду:

Довгий код Компактний код
var data = stream.getMetaData();
storage.save(data)
Ми отримали метадані з потоку stream і зберегли їх у сховищі storage. Який саме тип мала змінна data — неважливо.

Золота середина

Зараз наведемо три способи запису одного й того самого коду. Використання var буде оптимальним варіантом.

Код Примітка
dest.writeHeaderInfo(src.getFileMetaInfo());
Надто компактно
var headerInfo = src.getFileMetaInfo();
dest.writeHeaderInfo(headerInfo);
Ідеально
FileMetaInfo headerInfo = src.getFileMetaInfo();
dest.writeHeaderInfo(headerInfo);
Надто детально

Перейшовши від варіанту в рядку 1 до варіанту в рядку 2, ми завдяки імені змінної (headerInfo) додали коду трохи прочитності. Тепер ясно, що метод повертав не просто метаінформацію, а інформацію про заголовок.

Третій варіант був би надлишковим. Що з того, що headerInfo має тип FileMetaInfo — це й так було майже зрозуміло з методу getFileMetaInfo(). Набагато цікавішим є призначення цієї метаінформації.


13
Задача
Java Syntax Zero, 13 рівень, 6 лекція
Недоступна
Вперед у майбутнє
Вперед у майбутнє
13
Задача
Java Syntax Zero, 13 рівень, 6 лекція
Недоступна
Назад у минуле
Назад у минуле

3. Випущення типу — оператор diamond: <>

Ще до появи оператора var були спроби навчити компілятор виводити типи колекцій. Погодьтеся, цей запис на вигляд є трохи надлишковим:

ArrayList<String> list = new ArrayList<String>();

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

ArrayList<String> list = new ArrayList<>();

Як бачите, другий раз писати тип String вже не потрібно. Не так круто, як з оператором var, але свого часу й це здавалося досягненням.

Порожні трикутні дужки в типі колекції отримали назву оператор diamond: дві дужки віддалено нагадували силует діаманта.

Використовувати одночасно var і оператор diamond не вийде, так писати не можна:

var list = new ArrayList<>();

Інформації про тип, який зберігає колекція, зовсім не залишається.


13
Задача
Java Syntax Zero, 13 рівень, 6 лекція
Недоступна
Shine bright like a diamond
Shine bright like a diamond

4. Подвійні фігурні дужки

Пам'ятаєте швидку ініціалізацію масиву?

Ми там просто перелічували значення у фігурних дужках:

Приклади
int[] data = new int[] {1, 2, 3, 4, 5, 6, 7};
int[] data = {1, 2, 3, 4, 5, 6, 7};

Авторам мови Java сподобалася ідея використовувати фігурні дужки для спрощеного запису даних у масив. Але як бути з колекціями?

Для колекцій теж вистачило фантазії: дозволили використовувати трюк із подвійними фігурними дужками.

З цукром Без цукру
var list = new ArrayList<String>()
{{
   add("Привіт");
   add("Як");
   add("Справи");
}};
var list = new ArrayList<String>();

list.add("Привіт");
list.add("Як");
list.add("Справи");

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

Код не стає набагато компактнішим. Тут радше економія на дрібницях: не потрібно щоразу писати list. Це може бути вигідно, якщо ім'я змінної дуже довге.

Тож, зустрівши в чийомусь проєкті такий код, не дивуйтеся 🙂


13
Задача
Java Syntax Zero, 13 рівень, 6 лекція
Недоступна
Подвійні фігурні дужки
Подвійні фігурні дужки
Коментарі (20)
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ
Jaroslav Рівень 48
8 грудня 2024
Стаття про подвійні дужки І малюнок звідти:
Андрій Рівень 18
18 січня 2024
Кайф
19 листопада 2023
Профіту в подвійних дужках ніякого не бачу, тільки читабельність коду забирає, а скорочення коду мізерна
Микола Пінчук Рівень 17
7 травня 2024
+
Christopher Ward 595 Рівень 16
6 серпня 2024
Зараз тобі нема, а в взагалі має сенс, коли тобі руцями треба не 5 елементів а 50 заводити
Kostiantyn Bogatyrchuk Рівень 14 Expert
12 березня 2023
Програмісти люблять, коли якийсь складний код або логіку можна вмістити в пару рядків, і водночас код компактний і прочитний.
Roma Chernesh Рівень 16
23 січня 2023
Нове слово у статті: "метаінформація" (метадані) - це інформація, що допомогає обробляти іншу інформацію. Тобто, це вказівки, де що має знаходитися у структурі коду. Простий приклад: список глав наприкінці книги з "посиланнями" на якій сторінці, яка глава. Чи, наприклад, каталог книг у бібліотеці "Шевченко на букву Ш". У програмуванні використовується у таких випадках як автоматизація роботи програм (програма отримавши метадані, не чекає на запуск від людини, а сама обробляє інформацію і передає її іншій програмі). Чи для якогось документа метадані - це інформація "хто автор", "розмір файлу", "дата створення" та інше.
Ігор Рівень 41 Expert
9 червня 2023
простіше кажучи, метаданні - це данні про данні ( тобто, якась додаткова інформація про якусь сущність ), або частина даних з чогось. Наприклад: String string = " Hello world "; - це наші данні якщо ми візьмемо з цього тексту слово " Hello ", то це будуть метаданні змінної - string.
nveenespi Рівень 4
5 серпня 2024
Визначення вірне, тільки тут швидше за все йшлось про метадані які отримуємо з getClass();
dianosauric Рівень 42
23 вересня 2022
Я тут чай без цукру п’ю, а у кода є цукор :D
Игорь Чайка Рівень 32
3 травня 2022
У мене чомусь IntelliJ IDEA не розуміє слово var. в чому може бути проблема? я так розумію, що там java 8 використовується для ваших завдань і тому не працює?
Петро Ключук Рівень 21
17 липня 2022
Скоріш за все, довотиться здавати завдання "всліпу".
les_yeux_blancs Рівень 50
25 квітня 2023
Все він розуміє Думаю справа у тому, що ти намагався використати var у полях класу, а це робити не можна
PAMPERS Рівень 26
27 липня 2023
Онови jdk, тобі інтеліджі сама запропонує це зробити, якщо на помилці нажати alt+enter
Taras Woytowitch Рівень 16
11 січня 2022
Про ";" з подвійними фігурними дужками будьте уважні))
Харченко Иван Рівень 15
10 лютого 2022
Я, думаю, майже всі на це купились😁
Игорь Чайка Рівень 32
2 травня 2022
взагалі не побачив ";", поки комент не прочитав😀😁😂
kalkulator¹ Рівень 51
12 листопада 2022
хто ти воїн
Андрій Рівень 18
18 січня 2024
Я думав, що один на це купився😂
Володимир Рівень 26
14 березня 2025
Щоб не попадатися на таких дрібницях, треба завести звичку запускати код навіть без вимоги виводу інформації в задачі. На етапі компіляції вилізуть всі недоліки.