Ребята, спасибо, что уделили время заполнению анкеты! Я получила больше сотни ответов и ценных идей, буду внедрять💪
Многие писали, что присоединились недавно, поэтому на этой неделе будут подборки самых популярных статей. Если что-то пропустили — рекомендую прочесть.
Многие писали, что присоединились недавно, поэтому на этой неделе будут подборки самых популярных статей. Если что-то пропустили — рекомендую прочесть.
Подборка: подготовка к собеседованиям
🔥Рейтинг технологий в вакансиях HeadHunter🔥
Вопросы с собеседований:
▫️Сравнение переменных
▫️Как создать поток: 7 вариантов ответа
▫️Интерфейсы: поля и методы
▫️Интерфейсы: отличия от абстрактного класса
▫️Вопросы про юнит-тесты
🔥Рейтинг технологий в вакансиях HeadHunter🔥
Вопросы с собеседований:
▫️Сравнение переменных
▫️Как создать поток: 7 вариантов ответа
▫️Интерфейсы: поля и методы
▫️Интерфейсы: отличия от абстрактного класса
▫️Вопросы про юнит-тесты
Подборка: Java core и Java 8
⚙️Java core:
▫️Сборщики мусора. Плюсы и минусы G1
▫️Как работает переопределение методов?
▫️2 способа обхода коллекций
▫️Система типов и проверка аргументов
👑 Java 8:
▪️Stream API: обзор и основные методы
▪️Stream API: ускоряемся🚀
▪️HashMap в Java 8
▪️Функциональные интерфейсы: обзор
▪️Функциональные интерфейсы: best practices
⚙️Java core:
▫️Сборщики мусора. Плюсы и минусы G1
▫️Как работает переопределение методов?
▫️2 способа обхода коллекций
▫️Система типов и проверка аргументов
👑 Java 8:
▪️Stream API: обзор и основные методы
▪️Stream API: ускоряемся🚀
▪️HashMap в Java 8
▪️Функциональные интерфейсы: обзор
▪️Функциональные интерфейсы: best practices
Как JVM работает со строками, часть 1
По статистике OpenJDK в приложениях 15-50% памяти занимают экземпляры String. Это много, поэтому разработчики JVM прикладывают много усилий, чтобы оптимизировать работу со строками.
❓Как сэкономить память, если в системе миллионы экземпляров?
1️⃣ Уменьшить количество памяти под одну строку.
Мы уже разбирали этот случай: в java 9 вышло обновление Compact String и размер памяти под строки сократился до 2 раз.
2️⃣ Добавить кэширование.
Есть два способа создать экземпляр String:
🔸Через оператор new:
🔸Без оператора new:
▫️Проверить в String Pool, есть ли там такая строка.
▫️Если есть — вернуть её.
▫️Если нет — создать объект, поместить в кэш, вернуть.
❓Как реализован String pool?
Структура похожа на HashMap: хэш-таблица фиксированного размера с парами хэш — строка. В последних версиях java она занимает 64 МБ, при желании размер меняется с помощью флажка:
✅ Ответ на 1 вопрос перед постом:
Можно исправить ситуацию и добавить строчку в кэш методом intern():
Но если строка "Java" использовалась раньше и попала в кэш, то будет создана только одна строка — new String.
По статистике OpenJDK в приложениях 15-50% памяти занимают экземпляры String. Это много, поэтому разработчики JVM прикладывают много усилий, чтобы оптимизировать работу со строками.
❓Как сэкономить память, если в системе миллионы экземпляров?
1️⃣ Уменьшить количество памяти под одну строку.
Мы уже разбирали этот случай: в java 9 вышло обновление Compact String и размер памяти под строки сократился до 2 раз.
2️⃣ Добавить кэширование.
Есть два способа создать экземпляр String:
🔸Через оператор new:
String s = new String ("one");
В памяти создаётся новый объект.🔸Без оператора new:
String s = "one";В этом случае идёт работа с кэшем строк под названием String pool. Схема работы такая:
▫️Проверить в String Pool, есть ли там такая строка.
▫️Если есть — вернуть её.
▫️Если нет — создать объект, поместить в кэш, вернуть.
❓Как реализован String pool?
Структура похожа на HashMap: хэш-таблица фиксированного размера с парами хэш — строка. В последних версиях java она занимает 64 МБ, при желании размер меняется с помощью флажка:
-XX:StringTableSize=65536В следующем посте рассмотрим ещё два способа снижения издержек на строки.
✅ Ответ на 1 вопрос перед постом:
new String("Java") создаёт новый объект в хипе, s2 = "Java" создаёт объект в String pool. Это два разных объекта, поэтому при сравнении через == результат будет false.Можно исправить ситуацию и добавить строчку в кэш методом intern():
String s1="Java";✅Рассмотрим второй вопрос. О том, сколько строк создаётся в конструкции
String s2=new String("Java");
s2=s2.intern();
println(s1==s2); //true
String str=new String("Java");
Подвох в том, что для конструктора String нужен экземпляр String, поэтому создаётся 2 строки — "Java" и new String;Но если строка "Java" использовалась раньше и попала в кэш, то будет создана только одна строка — new String.
❤1
Какой GoF паттерн реализует String pool?
Anonymous Quiz
24%
Заместитель (Proxy)
28%
Приспособленец (Flyweight)
28%
Компоновщик (Composite)
20%
Посредник (Mediator)
👍1
А вот и второй вопрос, он должен был быть перед постом🤫
Сколько экземпляров String создаётся в этой строке кода:
Сколько экземпляров String создаётся в этой строке кода:
Как JVM работает со строками, часть 2
Ссылка на часть 1.
Сегодня рассмотрим ещё 2 простых, но эффективных приёма JVM по оптимизации строк.
Оба связаны со внутренним устройством String:
При использовании оператора new в памяти создаётся новый объект:
❓Почему заменяется только текст, а не вся строка?
Ссылки на строчку могут быть в десятках мест. Текст — внутреннее поле, его заменить гораздо проще
❓Почему совместим только с G1?
Нашла только один комментарий по теме: G1 – единственный сборщик мусора, в котором есть pinned regions. Это области, в которых не происходит дефрагментация. Но почему нельзя разместить хэш-таблицу в другом месте — непонятно😕
❓Почему опция по умолчанию не работает?
Deduplication хорошо экономит память, когда в программе через оператор new создаётся много похожих строк-долгожителей. Тогда экономится больше памяти, чем затраты на копирование в хэш-таблицу. По статистике OpenJDK таких случаев мало, поэтому StringDeduplication по умолчанию отключен.
Для активации добавьте при запуске VM флажок:
Хэшкод строки играет важную роль в хэш-таблицах String pool, Deduplication и других процессах JVM.
Внутри класса String хэш хранится как примитив:
Если хэш равен 0, то он пересчитывается каждый раз. Шанс этого очень низкий, но в Java 13 в String добавился флаг для нулевого хэша:
Итого: оптимизацией строк идёт по всем фронтам:
1️⃣ Структура данных (Java 9: Compact Strings)
2️⃣ Кэширование (String pool)
3️⃣ Оптимизация частных случаев (Java 8: String Deduplication)
4️⃣ Микрооптимизации (Java 13: флажок hashIsZero)
Ссылка на часть 1.
Сегодня рассмотрим ещё 2 простых, но эффективных приёма JVM по оптимизации строк.
Оба связаны со внутренним устройством String:
byte[] value — текстbyte coder — тип кодировкиint hash1️⃣ String Deduplication (Java 8)
При использовании оператора new в памяти создаётся новый объект:
String str = new String("12");
Отдельный JVM поток ищет в памяти экземпляры String и записывает их текст в хэш-таблицу:hash → byte[]Если поток находит дубликат, то заменяет ссылку в повторяющейся строке на ссылку из хэш-таблицы:
str.value = hashtable.valueНа текст дубликата больше нет ссылок, поэтому он удалится сборщиком мусора. Так можно сэкономить 5-30% памяти. Опция String Deduplication работает только со сборщиком G1, и по умолчанию отключена.
❓Почему заменяется только текст, а не вся строка?
Ссылки на строчку могут быть в десятках мест. Текст — внутреннее поле, его заменить гораздо проще
❓Почему совместим только с G1?
Нашла только один комментарий по теме: G1 – единственный сборщик мусора, в котором есть pinned regions. Это области, в которых не происходит дефрагментация. Но почему нельзя разместить хэш-таблицу в другом месте — непонятно😕
❓Почему опция по умолчанию не работает?
Deduplication хорошо экономит память, когда в программе через оператор new создаётся много похожих строк-долгожителей. Тогда экономится больше памяти, чем затраты на копирование в хэш-таблицу. По статистике OpenJDK таких случаев мало, поэтому StringDeduplication по умолчанию отключен.
Для активации добавьте при запуске VM флажок:
-XX:+UseStringDeduplicationЧтобы посмотреть, сколько памяти сэкономил Deduplication, можно вывести статистику Xlog:
-Xlog:stringdedup*=debug2️⃣ Оптимизация хэш-кода (Java 13)
Хэшкод строки играет важную роль в хэш-таблицах String pool, Deduplication и других процессах JVM.
Внутри класса String хэш хранится как примитив:
int hashВычисляется и сохраняется при первом вызове hashcode():
if (hash == 0) {
hash = ...
}
⛔️Минус такого решения:Если хэш равен 0, то он пересчитывается каждый раз. Шанс этого очень низкий, но в Java 13 в String добавился флаг для нулевого хэша:
boolean hashIsZeroПроверка того, что хэш-код ещё не посчитан, стала такой:
if (h == 0 && !hashIsZero)Теперь хэш-код всегда считается один раз.
Итого: оптимизацией строк идёт по всем фронтам:
1️⃣ Структура данных (Java 9: Compact Strings)
2️⃣ Кэширование (String pool)
3️⃣ Оптимизация частных случаев (Java 8: String Deduplication)
4️⃣ Микрооптимизации (Java 13: флажок hashIsZero)
👍3
Intellij IDEA: Memory view
❓Как в IDEA посмотреть количество объектов в памяти?
По умолчанию подсчёт объектов при дебаге выключен, потому что это тяжелая операция и сильно тормозит процесс отладки.
Чтобы включить:
1️⃣ В окне Debug найдите вкладку Memory View.
2️⃣ Нажмите на шестерёнку в Memory View и выберите
✅ Update Loaded Classes On Debugger Stop
Картинка с инструкцией внизу⬇️
Что показывает:
🔸Count - количество экземпляров
🔸Diff - изменения с прошлого шага
При каждой остановке информация о количестве объектов обновляется.
Так можно наглядно посмотреть на работу String pool. Помните, был вопрос:
Сколько строк создаётся в конструкции:
Поменяем код на
❓Как в IDEA посмотреть количество объектов в памяти?
По умолчанию подсчёт объектов при дебаге выключен, потому что это тяжелая операция и сильно тормозит процесс отладки.
Чтобы включить:
1️⃣ В окне Debug найдите вкладку Memory View.
2️⃣ Нажмите на шестерёнку в Memory View и выберите
✅ Update Loaded Classes On Debugger Stop
Картинка с инструкцией внизу⬇️
Что показывает:
🔸Count - количество экземпляров
🔸Diff - изменения с прошлого шага
При каждой остановке информация о количестве объектов обновляется.
Так можно наглядно посмотреть на работу String pool. Помните, был вопрос:
Сколько строк создаётся в конструкции:
String s = new String("Java");
Откроем Memory View. После выполнения строки напротив класса java.lang.String увидим Diff +2.Поменяем код на
String java = "Java";Запустим снова. "Java" в первой строке отправилась в String pool. Теперь после выполнения второй строки напротив java.lang.String будет Diff +1.
String s = new String("Java");
❤1
Паттерны GoF: инструкция по изучению
В 1994 вышла книжка Design Patterns: Elements of Reusable Object-Oriented Software. Авторов часто называют Gang of Four — Банда четырёх, а описанные в книге приёмы - паттернами GoF.
❓Зачем?
Паттерны активно используются на практике, а ещё помогут:
🔸Общаться с коллегами на одном языке и быстро обсуждать идеи.
🔸Проходить собеседования на джуниор и мидл позиции.
❓Что читать?
❌ Книга "Design Patterns: Elements of Reusable Object-Oriented Software"
Та самая книга. 1994 год, 440 страниц, примеры на С++. В 2020 году вышло обновлённое издание, но стиль изложения не изменился, читать тяжело.
❌ Википедия
Текст и диаграммы скопированы из книги Design patterns.
😐 Книга "Head First: Паттерны проектирования"
Простые описания, много картинок и примеров, но очень растянуто — 650 страниц.
✅ Каталог паттернов
Читать приятно, много схем и картинок. Всё по полочкам: какая проблема решается, преимущества и недостатки паттерна, сравнение паттернов между собой. Есть примеры на java.
Ресурс не идеален, но это лучшее по теме паттернов в интернете.
❓Какие сложности могут быть?
1️⃣ Формализм
Паттерны сами по себе простые. Некоторые из них вы использовали, не осознавая этого. Но определения паттернов максимально формальные. Все ресурсы описывают цель паттерна Мост так:
«Отделить абстракцию от реализации так, чтобы то и другое можно было изменять независимо»
Поэтому ориентируйтесь на примеры и картинки.
2️⃣ Непонятна разница между паттернами
Исходные задачи могут быть разными, а реализация в коде одна и та же. Это нормально, и часто встречается в структурных паттернах.
3️⃣ Мало реальных примеров
Для объяснения часто берут вымышленные примеры, хотя к каждому паттерну можно подобрать пример из JDK или Spring.
4️⃣ Не все одинаково полезны
Одни используются чаще, чем другие. Некоторые паттерны никогда не придётся писать самостоятельно:
▪️Итератор есть в каждой коллекции.
▪️Команда передаётся в лямбда выражениях.
▪️Синглтон легко создать через аннотацию Component в Spring.
Каждый паттерн - готовое решение конкретной проблемы. На практике всё может быть интереснее как по задачам, так и по реализации. Например, паттерн Builder может помочь при разработке многопоточных программ, а паттерн Proxy можно реализовать через AOP.
В 1994 вышла книжка Design Patterns: Elements of Reusable Object-Oriented Software. Авторов часто называют Gang of Four — Банда четырёх, а описанные в книге приёмы - паттернами GoF.
❓Зачем?
Паттерны активно используются на практике, а ещё помогут:
🔸Общаться с коллегами на одном языке и быстро обсуждать идеи.
🔸Проходить собеседования на джуниор и мидл позиции.
❓Что читать?
❌ Книга "Design Patterns: Elements of Reusable Object-Oriented Software"
Та самая книга. 1994 год, 440 страниц, примеры на С++. В 2020 году вышло обновлённое издание, но стиль изложения не изменился, читать тяжело.
❌ Википедия
Текст и диаграммы скопированы из книги Design patterns.
😐 Книга "Head First: Паттерны проектирования"
Простые описания, много картинок и примеров, но очень растянуто — 650 страниц.
✅ Каталог паттернов
Читать приятно, много схем и картинок. Всё по полочкам: какая проблема решается, преимущества и недостатки паттерна, сравнение паттернов между собой. Есть примеры на java.
Ресурс не идеален, но это лучшее по теме паттернов в интернете.
❓Какие сложности могут быть?
1️⃣ Формализм
Паттерны сами по себе простые. Некоторые из них вы использовали, не осознавая этого. Но определения паттернов максимально формальные. Все ресурсы описывают цель паттерна Мост так:
«Отделить абстракцию от реализации так, чтобы то и другое можно было изменять независимо»
Поэтому ориентируйтесь на примеры и картинки.
2️⃣ Непонятна разница между паттернами
Исходные задачи могут быть разными, а реализация в коде одна и та же. Это нормально, и часто встречается в структурных паттернах.
3️⃣ Мало реальных примеров
Для объяснения часто берут вымышленные примеры, хотя к каждому паттерну можно подобрать пример из JDK или Spring.
4️⃣ Не все одинаково полезны
Одни используются чаще, чем другие. Некоторые паттерны никогда не придётся писать самостоятельно:
▪️Итератор есть в каждой коллекции.
▪️Команда передаётся в лямбда выражениях.
▪️Синглтон легко создать через аннотацию Component в Spring.
Каждый паттерн - готовое решение конкретной проблемы. На практике всё может быть интереснее как по задачам, так и по реализации. Например, паттерн Builder может помочь при разработке многопоточных программ, а паттерн Proxy можно реализовать через AOP.
👍3
Java 15: sealed classes
В сентябре выйдет Java 15 с новой фичей: sealed classes.
Sealed классы и интерфейсы явно определяют список наследников:
Плюс в java.lang.Class добавилось два метода:
Глобальная цель - поддержка pattern matching. Чтобы вместо
При реализации паттерна State. Раньше конечный набор состояний выражался только через enum:
❌ Значения в конструкторе жёстко задаются на этапе компиляции.
✅ Каждое состояние в отдельном файле.
✅ Экземпляры создаются во время работы программы. Конструктор принимает параметры, а не константы.
В сентябре выйдет Java 15 с новой фичей: sealed classes.
Sealed классы и интерфейсы явно определяют список наследников:
public sealed class ShapeКлассы, которых нет в блоке permits, не могут наследоваться от sealed класса. Проверка идёт во время компиляции или в IDE. В Intellij IDEA уже в июле добавили поддержку sealed типов.
permits Circle, Rectangle
Плюс в java.lang.Class добавилось два метода:
🔸ClassDesc[] getPermittedSubclasses()❓Зачем?
🔸boolean isSealed()
Глобальная цель - поддержка pattern matching. Чтобы вместо
if (s instanceof Circle) {…}
else if (s instanceof Rectangle) {…}
использовать switch:switch (s) {
case Circle c -> …
case Rectangle r -> …
❓Где пригодятся sealed классы?При реализации паттерна State. Раньше конечный набор состояний выражался только через enum:
enum State {NEW, VERIFIED;}
❌ Все элементы и методы хранятся вместе. Если методов много, то размер файла растёт, и читаемость снижается.❌ Значения в конструкторе жёстко задаются на этапе компиляции.
enum State {
NEW(12);
int rating;
State(int rating) {…}
}
Теперь с помощью sealed класса:✅ Каждое состояние в отдельном файле.
✅ Экземпляры создаются во время работы программы. Конструктор принимает параметры, а не константы.
👍2
Intellij IDEA: редактирование кода
Несколько простых приёмов для быстрой работы.
Легендарные комбинации
работают со всей строкой, на которой стоит курсор, не нужно ничего выделять.
Удалить всю строку:
Чтобы переместить выделенный код:
Несколько простых приёмов для быстрой работы.
Легендарные комбинации
Ctrl + C
Ctrl + V
Ctrl + X работают со всей строкой, на которой стоит курсор, не нужно ничего выделять.
Удалить всю строку:
Ctrl + YДублировать строку:
Ctrl + DЧтобы выделить часть кода:
Ctrl + WПри каждом нажатии W захватывается всё большая область.
Чтобы переместить выделенный код:
Ctrl + Shift + ⬆️
Ctrl + Shift + ⬇️👍2
У вас крупная система: 30 микросервисов и 200 серверов, всё на java 8. Вы решили перейти на более новую версию в течение месяца. В сентябре выйдет java 15. На какую версию запланируете переход?
Anonymous Poll
6%
Java 9
65%
Java 11
17%
Java 14
12%
Java 15
Релизный цикл в java
15 сентября выйдет новая java — версия под номером 15. В этом посте разберёмся, каковы шансы увидеть её на вашем продакшене.
Java — распространённый язык, и требования к каждому релизу высоки. Ожидается, что новая версия будет удобной и быстро работать на всех процессорах. Разработка и тестирование занимают время, поэтому раньше java выходила раз в 3-5 лет. Между версиями выходили апдейты – исправления ошибок и безопасности.
Долгие релизы замедляют развитие. В 2017 году производители JVM перешли на короткие циклы: теперь новая версия выходит раз в полгода. Новые фичи быстрее попадают к пользователям, и можно быстро получить обратную связь.
❓В чём проблема?
В больших проектах десятки микросервисов, сотни и тысячи серверов. Переводить инфраструктуру на новые версии каждые полгода — так себе задача. При этом важно получать обновления, чтобы не было пробелов в безопасности.
В таких случаях подойдёт java с пометкой LTS (Long Time Support). Последняя LTS— java 11. Следующая — java 17, выйдет в сентябре 2021 года.
❓Чем LTS версия отличается от обычной?
Каждая версия java— проект с отдельной кодовой базой.
Если в коде JVM найдена ошибка, то в идеале она исправляется во всех версиях, и апдейт уходит всем пользователям. Чем больше версий поддерживается, тем больше времени занимает исправление ошибки, тестирование и подготовка апдейта.
В случае пробелов с безопасностью время терять нельзя. Поэтому обновление готовится только для последней версии (java 14) и для LTS версии (java 11).
Таким образом, java LTS получает апдейты в течение нескольких лет, остальные версии — в течение полугода.
На продакшене должна быть безопасная версия с наименьшим количеством ошибок. Поэтому доступны три варианта:
🔸Обновлять инфраструктуру каждые полгода
🔸Оставаться на LTS и обновляться раз в 3 года
🔸Платить за поддержку другой версии
Выбор зависит от размеров проекта и сложности обновления.
Ответ на вопрос перед постом
В больших системах тяжело менять версию каждые полгода, но важно получать все обновления. Поэтому подходящий вариант — придерживаться последней LTS версии - java 11.
15 сентября выйдет новая java — версия под номером 15. В этом посте разберёмся, каковы шансы увидеть её на вашем продакшене.
Java — распространённый язык, и требования к каждому релизу высоки. Ожидается, что новая версия будет удобной и быстро работать на всех процессорах. Разработка и тестирование занимают время, поэтому раньше java выходила раз в 3-5 лет. Между версиями выходили апдейты – исправления ошибок и безопасности.
Долгие релизы замедляют развитие. В 2017 году производители JVM перешли на короткие циклы: теперь новая версия выходит раз в полгода. Новые фичи быстрее попадают к пользователям, и можно быстро получить обратную связь.
❓В чём проблема?
В больших проектах десятки микросервисов, сотни и тысячи серверов. Переводить инфраструктуру на новые версии каждые полгода — так себе задача. При этом важно получать обновления, чтобы не было пробелов в безопасности.
В таких случаях подойдёт java с пометкой LTS (Long Time Support). Последняя LTS— java 11. Следующая — java 17, выйдет в сентябре 2021 года.
❓Чем LTS версия отличается от обычной?
Каждая версия java— проект с отдельной кодовой базой.
Если в коде JVM найдена ошибка, то в идеале она исправляется во всех версиях, и апдейт уходит всем пользователям. Чем больше версий поддерживается, тем больше времени занимает исправление ошибки, тестирование и подготовка апдейта.
В случае пробелов с безопасностью время терять нельзя. Поэтому обновление готовится только для последней версии (java 14) и для LTS версии (java 11).
Таким образом, java LTS получает апдейты в течение нескольких лет, остальные версии — в течение полугода.
На продакшене должна быть безопасная версия с наименьшим количеством ошибок. Поэтому доступны три варианта:
🔸Обновлять инфраструктуру каждые полгода
🔸Оставаться на LTS и обновляться раз в 3 года
🔸Платить за поддержку другой версии
Выбор зависит от размеров проекта и сложности обновления.
Ответ на вопрос перед постом
В больших системах тяжело менять версию каждые полгода, но важно получать все обновления. Поэтому подходящий вариант — придерживаться последней LTS версии - java 11.
❤1
Релизный цикл в java, часть 2
С 2017 года java выходит раз в полгода. В прошлом посте обсудили релизы, а в этом обсудим жизненный цикл нововведений.
Фичи в java проходит две стадии:
1️⃣ Предварительная — по умолчанию не работает. Полностью готова, но открыта для обратной связи. Методы и реализация неокончательные.
2️⃣ Финальная — доступна по умолчанию.
Терминология в JDK посложнее, названия стадий зависят от типа фичи:
🔸Новый синтаксис, класс:
Preview / Standard
🔸JVM функционал:
Experimental / Production
🔸Утилиты, новое API:
Incubator / Standard
В списке фич новой версии «предварительный» статус указывают в скобках:
— Скоро java 15 выйдет, а в проекте 8 версия. Технологии идут вперёд, а я трачу лучшие годы на легаси((
У всех крупных проектов такая ситуация.
Ближайшая LTS версия java выйдет в сентябре 2021. Большинство фич, о которых пишут статьи, сейчас в превью стадии. Они не доступны по умолчанию и войдут в обиход большинства проектов не раньше конца 2021 года.
Но можно попробовать уже сейчас:
1️⃣ Intellij IDEA
File → Project Structure → Project → Project Language Level
В списке выбрать версию с пометкой (Preview)
2️⃣ Maven
В плагины, которые работают с кодом (maven-compiler-plugin, maven-surefire-plugin) добавить секцию
javac --release 13 --enable-preview
Обратная связь по превью фичам собирается в Java Bug Database.
С 2017 года java выходит раз в полгода. В прошлом посте обсудили релизы, а в этом обсудим жизненный цикл нововведений.
Фичи в java проходит две стадии:
1️⃣ Предварительная — по умолчанию не работает. Полностью готова, но открыта для обратной связи. Методы и реализация неокончательные.
2️⃣ Финальная — доступна по умолчанию.
Терминология в JDK посложнее, названия стадий зависят от типа фичи:
🔸Новый синтаксис, класс:
Preview / Standard
🔸JVM функционал:
Experimental / Production
🔸Утилиты, новое API:
Incubator / Standard
В списке фич новой версии «предварительный» статус указывают в скобках:
360: Sealed Classes (Preview)Чем ближе выход java, тем больше статей о новых фичах — records, text blocks, sealed classes и т. д. Многие разработчики грустят:
383: Foreign-Memory Access API (Second Incubator)
384: Records (Second Preview)
— Скоро java 15 выйдет, а в проекте 8 версия. Технологии идут вперёд, а я трачу лучшие годы на легаси((
У всех крупных проектов такая ситуация.
Ближайшая LTS версия java выйдет в сентябре 2021. Большинство фич, о которых пишут статьи, сейчас в превью стадии. Они не доступны по умолчанию и войдут в обиход большинства проектов не раньше конца 2021 года.
Но можно попробовать уже сейчас:
1️⃣ Intellij IDEA
File → Project Structure → Project → Project Language Level
В списке выбрать версию с пометкой (Preview)
2️⃣ Maven
В плагины, которые работают с кодом (maven-compiler-plugin, maven-surefire-plugin) добавить секцию
<configuration>3️⃣ При компиляции через консоль добавить 2 аргумента
<argLine>--enable-preview</argLine>
</configuration>
javac --release 13 --enable-preview
Обратная связь по превью фичам собирается в Java Bug Database.
❤1
Чем записи (records) отличаются от классов?
Anonymous Poll
62%
Нельзя поменять значения полей
15%
Нельзя использовать дженерики
61%
Не участвуют в наследовании
12%
Нет методов equals, hashcode
25%
Нет статических полей и методов
40%
Нет приватных полей
Records: обзор
Записи (records) появились как превью фича в java 14. В этом посте разберём, что такое записи, чем отличаются от классов и как их использовать.
Записи определяют неизменяемый набор значений:
🔸 Поля нельзя поменять: ни внутри методов, ни через рефлекшн
🔸 Нет приватных полей
🔸 Не участвуют в наследовании
🔸 Конструктор по умолчанию не пустой, а с заданными полями
🔸 Добавлены геттеры по умолчанию:
🔸 Для сериализации не нужен serialVersionUID
Запись - специальный класс для хранения данных.
✅ Определять методы
✅ Реализовать интерфейсы
✅ Добавлять static поля и методы
✅ Ставить аннотации
✅ Использовать дженерики
Ещё одна особенность records — конструктор. Конструктор по умолчанию содержит все поля и называется канонический конструктор:
1️⃣ В многопоточных алгоритмах
Неизменяемые значения не нужно синхронизировать.
2️⃣ Data Transfer Object (DTO)
Для отправки данных пользователю или в другую систему.
Для упрощения сложного кода и большей читаемости.
4️⃣ Как составное возвращаемое значение
Когда не хочется создавать отдельный класс ради одного метода:
В записях поля неизменны, также записи не участвуют в наследовании и не содержат приватных полей.
Записи (records) появились как превью фича в java 14. В этом посте разберём, что такое записи, чем отличаются от классов и как их использовать.
Записи определяют неизменяемый набор значений:
record Point(int x, int y) {}
Создаются так же, как и другие классы:Point p = new Point(1,2);В чём особенность?
🔸 Поля нельзя поменять: ни внутри методов, ни через рефлекшн
🔸 Нет приватных полей
🔸 Не участвуют в наследовании
🔸 Конструктор по умолчанию не пустой, а с заданными полями
🔸 Добавлены геттеры по умолчанию:
p.x()🔸 toString по умолчанию
p.y()
Point[x=1, y=2]🔸 equals и hashcode по умолчанию
🔸 Для сериализации не нужен serialVersionUID
Запись - специальный класс для хранения данных.
record Point компилируется в public final class Point extends java/lang/RecordВсе остальные функции класса сохраняются:
✅ Определять методы
✅ Реализовать интерфейсы
✅ Добавлять static поля и методы
✅ Ставить аннотации
✅ Использовать дженерики
Ещё одна особенность records — конструктор. Конструктор по умолчанию содержит все поля и называется канонический конструктор:
public Point(int x, int y){
this.x=x;
this.y=y;
}
Он доступен по умолчанию, его можно не писать. Переопределяйте конструктор, если нужно добавить проверку аргументов:public Point(int x, int y){
if (x>100) throw new …
this.x=x;
this.y=y;
}
Для канонического конструктора есть краткая запись. Можно опустить присвоение переменных и оставить только нужные проверки:public Point {
if (x>100) throw new ...
}
Другие конструкторы должны вызывать канонический:public Point(int x) {
this(x,0);
}
Где использовать записи:1️⃣ В многопоточных алгоритмах
Неизменяемые значения не нужно синхронизировать.
2️⃣ Data Transfer Object (DTO)
Для отправки данных пользователю или в другую систему.
record UserDTO(long id, String name) {
public UserDTO(User user) {…}
}
3️⃣ Как промежуточные значения в Stream APIДля упрощения сложного кода и большей читаемости.
4️⃣ Как составное возвращаемое значение
Когда не хочется создавать отдельный класс ради одного метода:
record MinMax<T>(T min, T max) {}
❗️Правильный ответ на вопрос перед постом: В записях поля неизменны, также записи не участвуют в наследовании и не содержат приватных полей.
👍3
Как будете отмечать выход java 15?
Anonymous Poll
25%
Вкусным обедом
31%
Интеллектуальной беседой
24%
Вечерней пиццей
13%
Встречей с друзьями
34%
Убойной тренировкой
Records и немного теории
15 сентября выйдет java 15. Если вы отмечаете это событие интеллектуальной беседой под пиццу, то этот пост для вас. Здесь вы найдёте немного computer science на тему records.
Неизменяемые типы — основа функциональных языков. Записи — простые структуры, но за этой простотой стоит теоретический фундамент.
Система типов — теория, на основе которой проектируется язык программирования. Cегодня разберём классификацию, которая отвечает на вопрос:
❓Как определить тип объекта?
1️⃣ По имени. Тогда это номинальный тип
На основе имени проверяется возможность вызова методов и приведения типов друг к другу
2️⃣ По данным внутри объекта. Тогда это структурный тип.
Для них возможна запись:
✅
В java структурных типов нет и скорее всего не будет. В 2013 году обсуждалось, чтобы ввести в язык первый структурный тип под названием arrow type. Выглядел бы он так:
15 сентября выйдет java 15. Если вы отмечаете это событие интеллектуальной беседой под пиццу, то этот пост для вас. Здесь вы найдёте немного computer science на тему records.
Неизменяемые типы — основа функциональных языков. Записи — простые структуры, но за этой простотой стоит теоретический фундамент.
Система типов — теория, на основе которой проектируется язык программирования. Cегодня разберём классификацию, которая отвечает на вопрос:
❓Как определить тип объекта?
1️⃣ По имени. Тогда это номинальный тип
На основе имени проверяется возможность вызова методов и приведения типов друг к другу
record Point(int x,int y){}
record Time(int hours,int min){}
❌ Point p = new Time(1,1);
Записи по факту одинаковые — два целых числа. Но имена разные, поэтому типы между собой несовместимы. У номинальных типов проверки часто происходят на этапе компиляции.2️⃣ По данным внутри объекта. Тогда это структурный тип.
Для них возможна запись:
✅
Point p = new Time(1,1);
Структурные типы используются в функциональных языках и java script. Они добавляют больше гибкости, но менее управляемы.В java структурных типов нет и скорее всего не будет. В 2013 году обсуждалось, чтобы ввести в язык первый структурный тип под названием arrow type. Выглядел бы он так:
(String) → IntegerИдею отвергли из-за сложностей реализации и адаптации к существующим библиотекам. Альтернативное решение — лямбда-выражения, представляют похожую функциональность, но с чётко определённым типом:
Function<String,Integer> f =Все структуры в java номинальные. Записи - не исключение. Номинальность была в требованиях для реализации, а в анонсе records называют nominal tuples — номинальные кортежи.
str → str.length();
👍3