В чём разница между
Вот пример, иллюстрирующий разницу:
👉@BookJava
==
и .equals()
при сравнении строк?==
сравнивает ссылки на объекты (адреса в памяти), а .equals()
сравнивает содержимое строк. Для сравнения строк всегда используйте .equals()
.Вот пример, иллюстрирующий разницу:
String str1 = "Hello";
String str2 = "Hello";
String str3 = new String("Hello");
System.out.println(str1 == str2); // true (один и тот же объект)
System.out.println(str1 == str3); // false (разные объекты)
System.out.println(str1.equals(str2)); // true (одинаковое содержимое)
System.out.println(str1.equals(str3)); // true (одинаковое содержимое)
👉@BookJava
👍7💩2
💡10 незаменимых советов и приёмов Java, которые должен знать каждый разработчик
1. Используйте улучшенный цикл for
Улучшенный цикл for, появившийся в Java 5, позволяет лаконично и эффективно проходить по массивам и коллекциям. Вместо традиционного цикла с индексами можно итерироваться напрямую по элементам, что повышает читаемость кода и снижает вероятность ошибок выхода за пределы массива.
2. Используйте дженерики (Generics)
Дженерики позволяют создавать переиспользуемый код, работающий с разными типами данных. Они обеспечивают безопасность типов и избавляют от необходимости явного приведения типов. Результат — более надёжный и удобный для поддержки код.
3. Применяйте StringBuilder для работы со строками
При конкатенации большого количества строк или частых изменениях строки класс
4. Понимайте управление памятью в Java
Java автоматически управляет памятью через механизм сборщика мусора, но важно понимать, как создаются, используются и уничтожаются объекты. Грамотное управление памятью помогает избежать утечек и повышает производительность приложения.
5. Используйте неизменяемые классы (Immutable)
Неизменяемые классы потокобезопасны и дают преимущества в кэшировании, работе с многопоточностью и повышении безопасности. Создавая неизменяемые классы, вы исключаете риск случайных изменений и обеспечиваете целостность данных.
6. Применяйте try-with-resources
При работе с ресурсами, которые нужно закрывать (например, файлы или подключения к базе данных), конструкция
7. Используйте перечисления (enum) для констант
Если у вас есть набор связанных констант, лучше использовать
8. Оптимизируйте циклы с помощью break и continue
Оператор
9. Используйте библиотеки и фреймворки
В экосистеме Java есть огромное количество библиотек и фреймворков, которые упрощают разработку. Применяйте популярные решения вроде Apache Commons, Gson или Jackson для задач работы с файлами, JSON или базами данных. Это экономит время и избавляет от необходимости «изобретать велосипед».
10. Практикуйте грамотную обработку ошибок
Обработка ошибок — ключ к созданию надёжного и поддерживаемого кода. Используйте механизмы исключений для корректного перехвата и обработки ошибок. Логируйте важные сообщения и давайте пользователям понятную обратную связь при возникновении ошибок. Это облегчает отладку и улучшает пользовательский опыт.
👉@BookJava
1. Используйте улучшенный цикл for
Улучшенный цикл for, появившийся в Java 5, позволяет лаконично и эффективно проходить по массивам и коллекциям. Вместо традиционного цикла с индексами можно итерироваться напрямую по элементам, что повышает читаемость кода и снижает вероятность ошибок выхода за пределы массива.
int[] numbers = {1, 2, 3, 4, 5};
for (int number : numbers) {
System.out.println(number);
}
2. Используйте дженерики (Generics)
Дженерики позволяют создавать переиспользуемый код, работающий с разными типами данных. Они обеспечивают безопасность типов и избавляют от необходимости явного приведения типов. Результат — более надёжный и удобный для поддержки код.
List<String> names = new ArrayList<>();
names.add("John");
names.add("Jane");
String firstName = names.get(0);
3. Применяйте StringBuilder для работы со строками
При конкатенации большого количества строк или частых изменениях строки класс
StringBuilder
работает эффективнее, чем оператор +
или методы конкатенации. StringBuilder
изменяем (mutable) и предоставляет удобные методы для работы со строками.
StringBuilder message = new StringBuilder("Hello");
message.append(" World");
message.insert(5, " Java");
String result = message.toString();
4. Понимайте управление памятью в Java
Java автоматически управляет памятью через механизм сборщика мусора, но важно понимать, как создаются, используются и уничтожаются объекты. Грамотное управление памятью помогает избежать утечек и повышает производительность приложения.
5. Используйте неизменяемые классы (Immutable)
Неизменяемые классы потокобезопасны и дают преимущества в кэшировании, работе с многопоточностью и повышении безопасности. Создавая неизменяемые классы, вы исключаете риск случайных изменений и обеспечиваете целостность данных.
6. Применяйте try-with-resources
При работе с ресурсами, которые нужно закрывать (например, файлы или подключения к базе данных), конструкция
try-with-resources
гарантирует автоматическое закрытие ресурсов, даже если произойдут исключения. Это упрощает управление ресурсами и снижает риск утечек.
try (FileReader fileReader = new FileReader("data.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader)) {
String line = bufferedReader.readLine();
// Process the data
} catch (IOException e) {
// Handle the exception
}
7. Используйте перечисления (enum) для констант
Если у вас есть набор связанных констант, лучше использовать
enum
, а не простые переменные или целочисленные константы. Перечисления обеспечивают безопасность типов, улучшают читаемость кода и легко расширяются.
enum Days {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
Days today = Days.MONDAY;
8. Оптимизируйте циклы с помощью break и continue
Оператор
break
позволяет выйти из цикла досрочно, а continue
— пропустить текущую итерацию и перейти к следующей. Грамотное использование этих операторов делает код более эффективным и читаемым.
for (int i = 1; i <= 10; i++) {
if (i == 5) {
break; // Exit the loop when i equals 5
}
if (i % 2 == 0) {
continue; // Skip even numbers
}
System.out.println(i);
}
9. Используйте библиотеки и фреймворки
В экосистеме Java есть огромное количество библиотек и фреймворков, которые упрощают разработку. Применяйте популярные решения вроде Apache Commons, Gson или Jackson для задач работы с файлами, JSON или базами данных. Это экономит время и избавляет от необходимости «изобретать велосипед».
10. Практикуйте грамотную обработку ошибок
Обработка ошибок — ключ к созданию надёжного и поддерживаемого кода. Используйте механизмы исключений для корректного перехвата и обработки ошибок. Логируйте важные сообщения и давайте пользователям понятную обратную связь при возникновении ошибок. Это облегчает отладку и улучшает пользовательский опыт.
👉@BookJava
👍5❤4🔥3
⁉️ Хотите научиться строить масштабируемые и отказоустойчивые решения на Kafka?
На открытом уроке «Архитектурные паттерны работы с Kafka: от простого к масштабируемому» 13 августа в 18:00 МСК мы разберем основные паттерны и архитектурные подходы для работы с Kafka в микросервисах. Вы освоите Event Sourcing и CQRS и узнаете, как правильно обрабатывать ошибки и гарантировать доставку сообщений.
Этот урок откроет перед вами новые возможности: вы научитесь строить архитектуру для обработки больших потоков данных и получите опыт работы с реальными кейсами.
➡️ Присоединяйтесь и получите скидку на большой курс «Apache Kafka»: https://vk.cc/cOir4i
На открытом уроке «Архитектурные паттерны работы с Kafka: от простого к масштабируемому» 13 августа в 18:00 МСК мы разберем основные паттерны и архитектурные подходы для работы с Kafka в микросервисах. Вы освоите Event Sourcing и CQRS и узнаете, как правильно обрабатывать ошибки и гарантировать доставку сообщений.
Этот урок откроет перед вами новые возможности: вы научитесь строить архитектуру для обработки больших потоков данных и получите опыт работы с реальными кейсами.
➡️ Присоединяйтесь и получите скидку на большой курс «Apache Kafka»: https://vk.cc/cOir4i
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🤮1
💡Совет по Java №1: Прощай, многословные объявления переменных — здравствуй,
Java 8 vs Java 21 — Часть 1
Одно из самых заметных улучшений при переходе с Java 8 на современные версии — это введение локальной типовой инференции, более известной как ключевое слово
Проблема Java 8
В Java 8 приходилось явно указывать тип каждой локальной переменной, даже когда он был очевиден из контекста:
Эта многословность становилась особенно болезненной при работе с:
- сложными обобщёнными типами,
- шаблонами Builder,
- потоковыми операциями со сложными промежуточными типами.
Решение в Java 21
С
Примеры из реальной практики
1. Работа с коллекциями
2. Шаблоны проектирования
Когда использовать
✅ Хорошие случаи использования:
❌ Избегайте использования, когда:
Стратегия миграции
Постепенный подход к внедрению:
- Начните с очевидных случаев: сложные обобщённые типы, шаблоны Builder.
- Сфокусируйтесь на читаемости: используйте
- Поддерживайте единообразие: выработайте командные правила использования
- Проводите ревью и рефакторинг: обновляйте существующий код в процессе регулярного сопровождения.
Поддержка в IDE:
Большинство современных IDE отлично работают с
- IntelliJ IDEA: предлагает подсказки и отображает выведенные типы.
- Eclipse: показывает информацию о типе при наведении курсора.
- VS Code: расширения для Java поддерживают отображение выведенных типов.
Влияние на производительность
👉@BookJava
var
!Java 8 vs Java 21 — Часть 1
Одно из самых заметных улучшений при переходе с Java 8 на современные версии — это введение локальной типовой инференции, более известной как ключевое слово
var
. Появившееся в Java 10, это нововведение устраняет избыточные объявления типов и делает код чище и читаемее.Проблема Java 8
В Java 8 приходилось явно указывать тип каждой локальной переменной, даже когда он был очевиден из контекста:
// Java 8 - Verbose and redundant
Map<String, List<Customer>> customersByCity = new HashMap<String, List<Customer>>();
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Optional<Customer> customer = customerService.findById(123L);
Эта многословность становилась особенно болезненной при работе с:
- сложными обобщёнными типами,
- шаблонами Builder,
- потоковыми операциями со сложными промежуточными типами.
Решение в Java 21
С
var
компилятор автоматически выводит тип:
// Java 21 - Clean and concise
var customersByCity = new HashMap<String, List<Customer>>();
var names = Arrays.asList("Alice", "Bob", "Charlie");
var customer = customerService.findById(123L);
Примеры из реальной практики
1. Работа с коллекциями
// Before (Java 8)
List<Map<String, Object>> configurations = new ArrayList<Map<String, Object>>();
Map<String, List<ValidationResult>> validationResults = new ConcurrentHashMap<String, List<ValidationResult>>();
// After (Java 21)
var configurations = new ArrayList<Map<String, Object>>();
var validationResults = new ConcurrentHashMap<String, List<ValidationResult>>();
2. Шаблоны проектирования
// Before (Java 8)
HttpURLConnection connection = (HttpURLConnection) new URL("https://api.example.com")
.openConnection();
// After (Java 21)
var connection = (HttpURLConnection) new URL("https://api.example.com")
.openConnection();
```Java
3. Потоковые операции
```Java
// Before (Java 8)
Stream<String> filteredNames = customers.stream()
.map(Customer::getName)
.filter(name -> name.startsWith("A"));
// After (Java 21)
var filteredNames = customers.stream()
.map(Customer::getName)
.filter(name -> name.startsWith("A"));
Когда использовать
var
(лучшие практики)✅ Хорошие случаи использования:
// Clear from initialization
var users = new ArrayList<User>();
var config = ConfigurationBuilder.create().build();
var response = httpClient.execute(request);
// With method calls that have descriptive names
var isValid = validator.validateEmail(email);
var totalAmount = calculator.computeTotal(items);
❌ Избегайте использования, когда:
// Type is not obvious
var data = processData(); // What type is this?
var result = calculate(); // Unclear return type
// Primitives where explicitness helps
int count = 0; // Better than var count = 0;
boolean isActive = true; // Better than var isActive = true;
Стратегия миграции
Постепенный подход к внедрению:
- Начните с очевидных случаев: сложные обобщённые типы, шаблоны Builder.
- Сфокусируйтесь на читаемости: используйте
var
там, где он улучшает восприятие кода.- Поддерживайте единообразие: выработайте командные правила использования
var
.- Проводите ревью и рефакторинг: обновляйте существующий код в процессе регулярного сопровождения.
Поддержка в IDE:
Большинство современных IDE отлично работают с
var
:- IntelliJ IDEA: предлагает подсказки и отображает выведенные типы.
- Eclipse: показывает информацию о типе при наведении курсора.
- VS Code: расширения для Java поддерживают отображение выведенных типов.
Влияние на производительность
var
— это исключительно функция времени компиляции, без какого‑либо накладного расхода во время выполнения. Сгенерированный байткод полностью идентичен коду с явно указанными типами.👉@BookJava
👍4👎3❤2
Распространённые заблуждения
❌ «var делает Java динамически типизированным»
Неверно: Java остаётся статически типизированным языком. Компилятор по‑прежнему проверяет типы на этапе компиляции.
❌ «var ухудшает производительность»
Неверно: Никакого влияния на выполнение. Это всего лишь синтаксический сахар.
❌ «var снижает читаемость кода»
Зависит: При правильном использовании — улучшает читаемость, убирая лишний шум. При чрезмерном — может сделать код менее понятным.
Чек‑лист быстрой миграции
[ ] Найдите многословные объявления переменных в кодовой базе
[ ] Замените очевидные случаи на
[ ] Установите командные правила использования
[ ] Обновите процессы код‑ревью с учётом лучших практик применения
[ ] Используйте возможности IDE для проверки выведенных типов
Итог
Локальная типовая инференция с
Начните использовать
👉@BookJava
❌ «var делает Java динамически типизированным»
Неверно: Java остаётся статически типизированным языком. Компилятор по‑прежнему проверяет типы на этапе компиляции.
❌ «var ухудшает производительность»
Неверно: Никакого влияния на выполнение. Это всего лишь синтаксический сахар.
❌ «var снижает читаемость кода»
Зависит: При правильном использовании — улучшает читаемость, убирая лишний шум. При чрезмерном — может сделать код менее понятным.
Чек‑лист быстрой миграции
[ ] Найдите многословные объявления переменных в кодовой базе
[ ] Замените очевидные случаи на
var
(сложные дженерики, builders)[ ] Установите командные правила использования
var
[ ] Обновите процессы код‑ревью с учётом лучших практик применения
var
[ ] Используйте возможности IDE для проверки выведенных типов
Итог
Локальная типовая инференция с
var
— небольшое изменение, которое значительно улучшает читаемость кода и опыт разработчика. Речь не о том, чтобы писать меньше кода, а о том, чтобы писать более понятный и поддерживаемый код, избавляясь от избыточных объявлений типов.Начните использовать
var
уже сегодня — и сразу заметите, насколько чище станет ваш Java‑код!👉@BookJava
👎5👍4❤1
🧠 Можно ли переопределить
Нет, нельзя.
Метод
📌 Почему:
-
-
- Гарантирует, что при вызове
💡 Если хотите вернуть “свой” тип, делайте отдельный метод:
⚠️ Переопределяемый
👉 @BookJava
getClass()
в Java?Нет, нельзя.
Метод
getClass()
в java.lang.Object
объявлен так:
public final native Class<?> getClass();
📌 Почему:
-
final
— запрещает переопределение в наследниках.-
native
— реализован в JVM, а не на Java.- Гарантирует, что при вызове
obj.getClass()
всегда вернётся реальный класс объекта, без подмен и сюрпризов.💡 Если хотите вернуть “свой” тип, делайте отдельный метод:
class MyClass {
public String getTypeName() {
return "CustomType";
}
}
⚠️ Переопределяемый
getClass()
сломал бы рефлексию, сериализацию и кучу системных механизмов. Именно поэтому Java защищает его.👉 @BookJava
👍5❤2
This media is not supported in your browser
VIEW IN TELEGRAM
Spring Debugger: Working With Dynamic Database Connections Just Got Simpler
Туториал демонстрирует очень крутую фичу плагина Spring Debugger. При запуске Spring-приложения или тестов в режиме отладки этот плагин автоматически находит и регистрирует в секции DataSource подключения к БД, которые были подняты в Testcontainers. Далее с этим можно работать как со стандартными дата-сорсами: смотреть схему, данные, делать запросы и так далее. Это сильно упрощает жизнь при отладке подобных тестов.
https://blog.jetbrains.com/idea/2025/07/spring-debugger-working-with-dynamic-database-connections-just-got-simpler/
👉 @BookJava
Туториал демонстрирует очень крутую фичу плагина Spring Debugger. При запуске Spring-приложения или тестов в режиме отладки этот плагин автоматически находит и регистрирует в секции DataSource подключения к БД, которые были подняты в Testcontainers. Далее с этим можно работать как со стандартными дата-сорсами: смотреть схему, данные, делать запросы и так далее. Это сильно упрощает жизнь при отладке подобных тестов.
https://blog.jetbrains.com/idea/2025/07/spring-debugger-working-with-dynamic-database-connections-just-got-simpler/
👉 @BookJava
❤3👍1
Конструкторы в Java: виды, инициализация и примеры
В Java конструктор — это специальный метод, который автоматически вызывается при создании нового объекта. Он заботится о том, чтобы сразу «обеспечить» объект всеми необходимыми начальным значениями - как Lego‑инструкция, превращающая вас в сразу работающего робота.
Что важно знать о конструкторах:
- Конструктор по умолчанию
Создаётся автоматически, если вы не объявили ни одного конструктора. Не имеет параметров и не задаёт пользовательские значения - поля получают только значения по умолчанию.
- Конструктор с параметрами
Позволяет инициализировать объект сразу нужными данными:
В этом примере мы сразу получаем дом с двумя этажами, синим цветом и гаражом - благодаря конструктору
- Конструктор копирования
Создает новую копию существующего объекта со всеми его полями - полезно, если нужно сохранить исходное состояние или избежать его изменения.
Перегрузка конструкторов - гибкость и удобство
Можно объявить несколько конструкторов в классе с разными параметрами:
Такой подход позволяет создавать объекты
Ещё один пример - класс
Получили объект
- Конструктор = автоматическая инициализация объекта.
- Виды: по умолчанию, с параметрами, копирующий.
- Перегрузка - возможность гибко задавать разные способы создания объектов.
- Это делает код чище, логичнее и безопаснее.
👉 @BookJava
В Java конструктор — это специальный метод, который автоматически вызывается при создании нового объекта. Он заботится о том, чтобы сразу «обеспечить» объект всеми необходимыми начальным значениями - как Lego‑инструкция, превращающая вас в сразу работающего робота.
Что важно знать о конструкторах:
- Конструктор по умолчанию
Создаётся автоматически, если вы не объявили ни одного конструктора. Не имеет параметров и не задаёт пользовательские значения - поля получают только значения по умолчанию.
- Конструктор с параметрами
Позволяет инициализировать объект сразу нужными данными:
House myHouse = new House(2, "Синий", true);
В этом примере мы сразу получаем дом с двумя этажами, синим цветом и гаражом - благодаря конструктору
House(...)
. - Конструктор копирования
Создает новую копию существующего объекта со всеми его полями - полезно, если нужно сохранить исходное состояние или избежать его изменения.
Перегрузка конструкторов - гибкость и удобство
Можно объявить несколько конструкторов в классе с разными параметрами:
class Book {
String title;
String author;
int year;
// По умолчанию
Book() {
this.title = "Неизвестно";
this.author = "Неизвестно";
this.year = 0;
}
// Только с названием
Book(String title) { /*...*/ }
// Полная инициализация
Book(String title, String author, int year) { /*...*/ }
}
Такой подход позволяет создавать объекты
Book
с разными уровнями наполненности в зависимости от ситуации.Ещё один пример - класс
Person
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
}
Person person = new Person("Алексей", 30);
Получили объект
person
сразу с заданными именем и возрастом - без лишнего кода. - Конструктор = автоматическая инициализация объекта.
- Виды: по умолчанию, с параметрами, копирующий.
- Перегрузка - возможность гибко задавать разные способы создания объектов.
- Это делает код чище, логичнее и безопаснее.
👉 @BookJava
👍2🤓2❤1
🚀 Хотите научиться интегрировать Apache Kafka и ClickHouse для эффективной обработки и анализа данных? 🚀
Присоединяйтесь к открытому уроку 20 августа в 20:00 МСК!
📚 Мы разберём, как настроить потоковую передачу данных, обеспечить надёжность и производительность, а также оптимизировать хранение и запросы. Вы узнаете, как использовать нативные коннекторы и Kafka Connect для интеграции этих двух мощных инструментов.
Мы покажем реальные кейсы, лучшие практики и как избежать частых ошибок при работе с Kafka и ClickHouse. Это знание поможет вам настроить эффективный pipeline и ускорить загрузку данных.
Присоединяйтесь и получите скидку на курс «Apache Kafka»:
https://vk.cc/cOz3C2
🎯 Не пропустите!
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
Присоединяйтесь к открытому уроку 20 августа в 20:00 МСК!
📚 Мы разберём, как настроить потоковую передачу данных, обеспечить надёжность и производительность, а также оптимизировать хранение и запросы. Вы узнаете, как использовать нативные коннекторы и Kafka Connect для интеграции этих двух мощных инструментов.
Мы покажем реальные кейсы, лучшие практики и как избежать частых ошибок при работе с Kafka и ClickHouse. Это знание поможет вам настроить эффективный pipeline и ускорить загрузку данных.
Присоединяйтесь и получите скидку на курс «Apache Kafka»:
https://vk.cc/cOz3C2
🎯 Не пропустите!
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
☕ Совет дня по Java: JDK vs JRE vs JVM
🔹 JVM (Java Virtual Machine)
Машина, которая выполняет Java-байткод, обеспечивая кроссплатформенность.
🔹 JRE (Java Runtime Environment)
Содержит JVM + необходимые библиотеки для запуска Java-приложений.
🔹 JDK (Java Development Kit)
Всё, что нужно разработчику — JRE + компилятор + инструменты для написания, компиляции и отладки Java-кода.
👉 Если запускаешь Java-приложения → тебе нужен JRE
👉 Если разрабатываешь Java-приложения → тебе нужен JDK
👉 А выполняет всю тяжёлую работу всегда JVM.
👉 @BookJava
🔹 JVM (Java Virtual Machine)
Машина, которая выполняет Java-байткод, обеспечивая кроссплатформенность.
🔹 JRE (Java Runtime Environment)
Содержит JVM + необходимые библиотеки для запуска Java-приложений.
🔹 JDK (Java Development Kit)
Всё, что нужно разработчику — JRE + компилятор + инструменты для написания, компиляции и отладки Java-кода.
👉 Если запускаешь Java-приложения → тебе нужен JRE
👉 Если разрабатываешь Java-приложения → тебе нужен JDK
👉 А выполняет всю тяжёлую работу всегда JVM.
👉 @BookJava
👍2❤1
В чем разница между перегрузкой метода и переопределением метода в Java?
🧠 Перегрузка метода (Method Overloading)
Это когда в одном классе есть методы с одинаковым именем, но разными сигнатурами (количеством или типами параметров).
* Компилятор выбирает метод на этапе compile-time.
* Можно менять:
* количество параметров
* тип параметров
* порядок параметров
* Нельзя перегружать метод, меняя только возвращаемый тип.
💡 Пример:
🧠 Переопределение метода (Method Overriding)
Это когда в классе-наследнике мы заново реализуем метод, который уже определён в родительском классе или интерфейсе.
* Определяется на этапе runtime (динамический полиморфизм).
* Сигнатура метода должна быть та же (имя, параметры, порядок, типы).
* Возвращаемый тип может быть ковариантным (подтипом оригинального).
* Доступ не может быть строже, чем у родительского метода.
* Метод родителя должен быть
* Для обязательности переопределения используют
💡 Пример:
👉 @BookJava
🧠 Перегрузка метода (Method Overloading)
Это когда в одном классе есть методы с одинаковым именем, но разными сигнатурами (количеством или типами параметров).
* Компилятор выбирает метод на этапе compile-time.
* Можно менять:
* количество параметров
* тип параметров
* порядок параметров
* Нельзя перегружать метод, меняя только возвращаемый тип.
💡 Пример:
public class MathUtil {
public int sum(int a, int b) { return a + b; }
public double sum(double a, double b) { return a + b; }
public int sum(int a, int b, int c) { return a + b + c; }
}
🧠 Переопределение метода (Method Overriding)
Это когда в классе-наследнике мы заново реализуем метод, который уже определён в родительском классе или интерфейсе.
* Определяется на этапе runtime (динамический полиморфизм).
* Сигнатура метода должна быть та же (имя, параметры, порядок, типы).
* Возвращаемый тип может быть ковариантным (подтипом оригинального).
* Доступ не может быть строже, чем у родительского метода.
* Метод родителя должен быть
public
/ protected
(не private
).* Для обязательности переопределения используют
@Override
.💡 Пример:
class Animal {
public void makeSound() {
System.out.println("Some sound");
}
}
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Woof!");
}
}
👉 @BookJava
👍3
⚙️ Микросервисы начинают тормозить под нагрузкой?
💡 Узнайте, как масштабировать и оптимизировать систему с помощью CQRS и Event Sourcing на .NET Aspire.
На открытом вебинаре «Оптимизация микросервисов с CQRS и Event Sourcing на .NET Aspire» 19 августа в 20:00 МСК разберем:
◽️ Ограничения классических микросервисов при высокой нагрузке.
◽️ Принципы разделения команд и запросов (CQRS) и хранения истории через Event Sourcing.
◽️ Практическую реализацию: сервис заказов с «команда-обработчик» и хранением событий в MongoDB.
◽️ Конфигурацию проекций для чтения данных.
❗️ Вы освоите оркестрацию через .NET Aspire (API Gateway, Order Service, база событий), внедрите логирование и трейсинг через OpenTelemetry, а также протестируете создание заказа, обновление статуса и визуализацию потока событий.
➡️ Посетите открытый урок и получите скидку на большое обучение «C# ASP.NET Core разработчик»: https://vk.cc/cOz6s4
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
💡 Узнайте, как масштабировать и оптимизировать систему с помощью CQRS и Event Sourcing на .NET Aspire.
На открытом вебинаре «Оптимизация микросервисов с CQRS и Event Sourcing на .NET Aspire» 19 августа в 20:00 МСК разберем:
◽️ Ограничения классических микросервисов при высокой нагрузке.
◽️ Принципы разделения команд и запросов (CQRS) и хранения истории через Event Sourcing.
◽️ Практическую реализацию: сервис заказов с «команда-обработчик» и хранением событий в MongoDB.
◽️ Конфигурацию проекций для чтения данных.
❗️ Вы освоите оркестрацию через .NET Aspire (API Gateway, Order Service, база событий), внедрите логирование и трейсинг через OpenTelemetry, а также протестируете создание заказа, обновление статуса и визуализацию потока событий.
➡️ Посетите открытый урок и получите скидку на большое обучение «C# ASP.NET Core разработчик»: https://vk.cc/cOz6s4
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
❤1
Когда лучше использовать
Record vs Class в Java ☕️📦
С 2021-го в Java появилась новая зверушка -
Сначала все радовались: "О, меньше кода, equals/hashCode/constructor сами пишутся!" 🎉
А потом пошли странные вопросы в код-ревью:
Разберёмся, когда record - подарок, а когда - мина замедленного действия.
Немного теории 📚
- Автоматическим конструктором по всем полям.
-
- Неизменяемыми (final) полями.
- Неявным
Это всё звучит прекрасно, но у этого есть архитектурные последствия.
Когда
1. DTO / данные без логики
Когда объект нужен просто как "контейнер" для данных, особенно при обмене между сервисами.
2. Иммутабельные объекты
Нет сеттеров, нет сюрпризов. Многопоточка будет тебе благодарна ❤️.
3. Модели конфигураций
Конфиг парсится один раз — и потом спокойно читается везде.
4. Key-объекты для Map/Set
Так как
Когда
1. Сложная логика внутри
Если объект должен уметь менять своё состояние,
2. Наследование
Record - всегда
3. ORM (например, Hibernate)
Многие ORM любят пустые конструкторы и сеттеры. С
4. Сериализация с изменениями
Если JSON-модель в будущем изменится,
Хитрости и подводные камни ⚠️
- Можно добавлять методы в record.
- Поля можно менять через рефлексию (но не надо — это ломает смысл
- Не стоит превращать record в «богатый объект» с кучей логики — это будет запутывать.
Итог 💡
- Берём record, когда нужна простая, иммутабельная структура данных без лишней логики.
- Берём class, когда есть сложное поведение, наследование, интеграция с фреймворками вроде Hibernate.
А вот если ты пишешь DTO и у тебя до сих пор class с геттерами/сеттерами, то, возможно, ты застрял в 2010-м 😏.
👉 @BookJava
record
, а когда class
в Java.Record vs Class в Java ☕️📦
С 2021-го в Java появилась новая зверушка -
record
.Сначала все радовались: "О, меньше кода, equals/hashCode/constructor сами пишутся!" 🎉
А потом пошли странные вопросы в код-ревью:
"А почему у тебя тут record, а не class?"
"record же immutable, а ты тут мутируешь поле через рефлексию, ты что…"
Разберёмся, когда record - подарок, а когда - мина замедленного действия.
Немного теории 📚
record
в Java — это особый вид final-класса с:- Автоматическим конструктором по всем полям.
-
equals
, hashCode
и toString
из коробки.- Неизменяемыми (final) полями.
- Неявным
private final
для каждого компонента.Это всё звучит прекрасно, но у этого есть архитектурные последствия.
Когда
record
- лучший выбор ✅1. DTO / данные без логики
Когда объект нужен просто как "контейнер" для данных, особенно при обмене между сервисами.
public record UserDto(String name, int age) {}
2. Иммутабельные объекты
Нет сеттеров, нет сюрпризов. Многопоточка будет тебе благодарна ❤️.
3. Модели конфигураций
Конфиг парсится один раз — и потом спокойно читается везде.
4. Key-объекты для Map/Set
Так как
equals
и hashCode
генерятся честно и по всем полям - отличная стабильная ключевая структура.Когда
class
лучше 🚫1. Сложная логика внутри
Если объект должен уметь менять своё состояние,
record
тебе мешает: поля final, сеттеров нет.2. Наследование
Record - всегда
final
. Забудь про расширение.3. ORM (например, Hibernate)
Многие ORM любят пустые конструкторы и сеттеры. С
record
они просто не подружатся (даже если будут пытаться через магию).4. Сериализация с изменениями
Если JSON-модель в будущем изменится,
record
будет ломаться при парсинге, потому что конструктор фиксирован.Хитрости и подводные камни ⚠️
- Можно добавлять методы в record.
public record Point(int x, int y) {
public double length() {
return Math.sqrt(x*x + y*y);
}
}
- Поля можно менять через рефлексию (но не надо — это ломает смысл
record
).- Не стоит превращать record в «богатый объект» с кучей логики — это будет запутывать.
Итог 💡
- Берём record, когда нужна простая, иммутабельная структура данных без лишней логики.
- Берём class, когда есть сложное поведение, наследование, интеграция с фреймворками вроде Hibernate.
record
- это не замена class
, а инструмент для конкретных задач.А вот если ты пишешь DTO и у тебя до сих пор class с геттерами/сеттерами, то, возможно, ты застрял в 2010-м 😏.
👉 @BookJava
❤4👍3🤡2
Pattern Matching в
Pattern Matching в
Ты наверняка видел такие простыни:
Знакомо? 😅
Тут и дублирование, и касты, и вечная путаница.
Что пришло с Java 17+ 🌟
Теперь можно использовать Pattern Matching прямо в
Красота:
✅ Нет ручных кастов
✅ Нет
✅ Всё читается как декларативное описание
А если хочется добавить условия? 🤔
Можно так:
Тут
Оно проверяется после совпадения типа, и только тогда срабатывает ветка.
Сравним 🥊
До Java 17: каша из
После Java 17: один чистый
Итог 💡
- Используй
- Код становится декларативным и компактным.
- А главное — исчезают дубли и лишние касты.
👉 @BookJava
switch
.Pattern Matching в
switch
— убийца if-else
цепочек ⚔️Ты наверняка видел такие простыни:
if (obj instanceof String) {
System.out.println("Строка длиной " + ((String) obj).length());
} else if (obj instanceof Integer) {
System.out.println("Целое число " + obj);
} else if (obj instanceof List) {
System.out.println("Список размером " + ((List<?>) obj).size());
} else {
System.out.println("Неизвестный тип");
}
Знакомо? 😅
Тут и дублирование, и касты, и вечная путаница.
Что пришло с Java 17+ 🌟
Теперь можно использовать Pattern Matching прямо в
switch
:
switch (obj) {
case String s -> System.out.println("Строка длиной " + s.length());
case Integer i -> System.out.println("Целое число " + i);
case List<?> l -> System.out.println("Список размером " + l.size());
default -> System.out.println("Неизвестный тип");
}
Красота:
✅ Нет ручных кастов
✅ Нет
else if
простыней✅ Всё читается как декларативное описание
А если хочется добавить условия? 🤔
Можно так:
switch (obj) {
case String s when s.length() > 5 ->
System.out.println("Длинная строка");
case String s ->
System.out.println("Короткая строка");
default ->
System.out.println("Что-то другое");
}
Тут
when
— это guard condition.Оно проверяется после совпадения типа, и только тогда срабатывает ветка.
Сравним 🥊
До Java 17: каша из
if-else
, ручные касты.После Java 17: один чистый
switch
, никакой боли.Итог 💡
- Используй
switch
с pattern matching, когда у тебя много разных подтипов или вход может быть разным типом.- Код становится декларативным и компактным.
- А главное — исчезают дубли и лишние касты.
👉 @BookJava
👍7
🔧 Сложности с масштабированием консьюмеров в RabbitMQ? Узнайте, как избежать ошибок, которые могут привести к потерям в порядке обработки сообщений.
📅 На открытом уроке 21 августа в 20:00 МСК разберём реальные кейсы и покажем, как правильно масштабировать консьюмеры, сохраняя порядок обработки. Узнаете, какие проблемы могут возникнуть при некорректном масштабировании и как их решить.
🎯 Получите ценные знания по прогнозированию и устранению проблем, повысите производительность системы и избегайте критических ошибок.
🚀 Зарегистрируйтесь на вебинар и получите в подарок записи трёх уроков по «Symfony», а также скидку на полный курс «Symfony Framework». Подарки доступны всем участникам! Регистрация по ссылке:
https://vk.cc/cOFmfT
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
📅 На открытом уроке 21 августа в 20:00 МСК разберём реальные кейсы и покажем, как правильно масштабировать консьюмеры, сохраняя порядок обработки. Узнаете, какие проблемы могут возникнуть при некорректном масштабировании и как их решить.
🎯 Получите ценные знания по прогнозированию и устранению проблем, повысите производительность системы и избегайте критических ошибок.
🚀 Зарегистрируйтесь на вебинар и получите в подарок записи трёх уроков по «Symfony», а также скидку на полный курс «Symfony Framework». Подарки доступны всем участникам! Регистрация по ссылке:
https://vk.cc/cOFmfT
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
👍1
Sealed Classes.
Sealed Classes — контроль наследования в Java 🔒
Одна из самых недооценённых фич Java 17 — sealed классы.
Если коротко: теперь ты можешь жёстко контролировать, кто именно может наследоваться от твоего класса.
До Java 17 🤯
Представь, у тебя есть базовый класс:
И куча наследников кто во что горазд:
А потом в коде появляются неожиданные "левые" реализации, и поддержка превращается в ад.
В Java 17 пришло спасение 🦸
Теперь только указанные классы могут наследовать
Больше никаких сюрпризов из сторонних либ или неосторожных рук джуна.
Варианты модификаторов 🛠️
У наследников есть три опции:
1.
2.
3.
Зачем это вообще? 🤔
✅ Чёткий контроль иерархии (никакой анархии).
✅ Более безопасный
✅ Понятный контракт: сразу видно, какие подтипы есть.
Пример использования с
И всё!
Если ты забыл какой-то подтип, компилятор не даст собрать проект 🚨.
Итог ⚡️
- Sealed Classes = контроль + безопасность + читаемость.
- В паре с Pattern Matching в switch это превращается в почти алгебраические типы данных (как в Kotlin или Scala).
- Если у тебя чётко ограниченный набор сущностей — sealed классы must-have.
👉 @BookJava
Sealed Classes — контроль наследования в Java 🔒
Одна из самых недооценённых фич Java 17 — sealed классы.
Если коротко: теперь ты можешь жёстко контролировать, кто именно может наследоваться от твоего класса.
До Java 17 🤯
Представь, у тебя есть базовый класс:
abstract class Shape {}
И куча наследников кто во что горазд:
Circle
, Rectangle
, Triangle
, StarShape
, ShapeFromLegacyLib
...А потом в коде появляются неожиданные "левые" реализации, и поддержка превращается в ад.
В Java 17 пришло спасение 🦸
public sealed abstract class Shape
permits Circle, Rectangle, Triangle {}
Теперь только указанные классы могут наследовать
Shape
.Больше никаких сюрпризов из сторонних либ или неосторожных рук джуна.
Варианты модификаторов 🛠️
У наследников есть три опции:
1.
final
— дальше наследовать нельзя.
public final class Circle extends Shape {}
2.
sealed
— продолжаем ограничивать список наследников.
public sealed class Rectangle extends Shape
permits Square {}
3.
non-sealed
— снимаем ограничения, и от этого класса можно наследоваться свободно.
public non-sealed class Triangle extends Shape {}
Зачем это вообще? 🤔
✅ Чёткий контроль иерархии (никакой анархии).
✅ Более безопасный
switch
с pattern matching: компилятор проверяет, что ты обработал все варианты.✅ Понятный контракт: сразу видно, какие подтипы есть.
Пример использования с
switch
💡
static String print(Shape shape) {
return switch (shape) {
case Circle c -> "Круг";
case Rectangle r -> "Прямоугольник";
case Triangle t -> "Треугольник";
};
}
И всё!
Если ты забыл какой-то подтип, компилятор не даст собрать проект 🚨.
Итог ⚡️
- Sealed Classes = контроль + безопасность + читаемость.
- В паре с Pattern Matching в switch это превращается в почти алгебраические типы данных (как в Kotlin или Scala).
- Если у тебя чётко ограниченный набор сущностей — sealed классы must-have.
👉 @BookJava
👍8❤1
Парсинг на Java. От основ до парсинга Яндекс Карт
Сегодня я рассмотрю основы парсинга на Java, используя как пример Яндекс Карты.
В этой статье мы рассмотрим, что такое HTTP и какие бывают методы запроса, как работать с HttpClient в Java 11+, как отправлять GET и POST-запросы, как обрабатывать HTTP-ответы и извлекать данные, и как всё это можно использовать для парсинга данных с внешнего сервера на примере Яндекс Карт.
https://habr.com/ru/companies/amvera/articles/937894/
👉 @BookJava
Сегодня я рассмотрю основы парсинга на Java, используя как пример Яндекс Карты.
В этой статье мы рассмотрим, что такое HTTP и какие бывают методы запроса, как работать с HttpClient в Java 11+, как отправлять GET и POST-запросы, как обрабатывать HTTP-ответы и извлекать данные, и как всё это можно использовать для парсинга данных с внешнего сервера на примере Яндекс Карт.
https://habr.com/ru/companies/amvera/articles/937894/
👉 @BookJava
20 августа (уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
Как выполнять итерацию по коллекции в Java?
Коллекция в Java — это объект, который группирует несколько элементов в единое целое и является частью Java Collections Framework. Она часто используется для хранения, извлечения, обработки и передачи агрегированных данных.
Чтобы пройтись по коллекции, можно использовать цикл for-each, итератор или традиционный цикл for. Пример ниже показывает использование for-each и обычного цикла for:
👉 @BookJava
Коллекция в Java — это объект, который группирует несколько элементов в единое целое и является частью Java Collections Framework. Она часто используется для хранения, извлечения, обработки и передачи агрегированных данных.
Чтобы пройтись по коллекции, можно использовать цикл for-each, итератор или традиционный цикл for. Пример ниже показывает использование for-each и обычного цикла for:
// Example using for-each loop:
List<String> fruits = Arrays.asList("Apple", "Banana", "Orange");
for (String fruit : fruits) {
System.out.println(fruit);
}
// Example using regular for loop:
for (int i = 0; i < fruits.size(); i++) {
System.out.println(fruits.get(i));
}
👉 @BookJava
👍3🥱2
Kafka уже стала стандартом для высоконагруженных систем, а Schema Registry — ключом к надёжной работе с данными.
Хотите уверенно интегрировать их в свои Java-проекты?
Приглашаем на открытый урок
🗓 26 августа в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «Java Developer. Professional».
🎯 О чём поговорим:
👥 Кому будет интересно:
Java-разработчикам и архитектам, работающим с распределёнными системами, а также DevOps-инженерам, внедряющим Kafka в продакшен.
💡В результате урока вы:
— Освоите ключевые подходы к созданию надёжных Kafka-приложений на Java.
— Научитесь эффективно управлять схемами данных в Schema Registry и оптимизировать производительность ваших систем.
🔗 Ссылка на регистрацию: https://vk.cc/cOK2dx
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
🤮1