19 ноября(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
Зачем нужен HashMap, если есть Hashtable?
☕ Методы класса Hashtable синхронизированы, что приводит к снижению производительности, а HashMap - нет;
☕ HashTable не может содержать элементы null, тогда как HashMap может содержать один ключ null и любое количество значений null;
☕ Iterator у HashMap, в отличие от Enumeration у HashTable, работает по принципу «fail-fast» (выдает исключение при любой несогласованности данных).
Hashtable это устаревший класс и его использование не рекомендовано.
👉 @java_geek
☕ Методы класса Hashtable синхронизированы, что приводит к снижению производительности, а HashMap - нет;
☕ HashTable не может содержать элементы null, тогда как HashMap может содержать один ключ null и любое количество значений null;
☕ Iterator у HashMap, в отличие от Enumeration у HashTable, работает по принципу «fail-fast» (выдает исключение при любой несогласованности данных).
Hashtable это устаревший класс и его использование не рекомендовано.
👉 @java_geek
👍3❤1
Что такое Local Variable?
Популярный вопрос на собеседовании Java-разработчика. Local variable — это переменная, которая определена внутри метода и существует вплоть до того момента, пока выполняется этот метод. Как только выполнение закончится, локальная переменная перестанет существовать.
Вот программа, которая использует локальную переменную helloMessage в методе main().
👉 @java_geek
Популярный вопрос на собеседовании Java-разработчика. Local variable — это переменная, которая определена внутри метода и существует вплоть до того момента, пока выполняется этот метод. Как только выполнение закончится, локальная переменная перестанет существовать.
Вот программа, которая использует локальную переменную helloMessage в методе main().
👉 @java_geek
👍1
Что такое «сессия»?
Сессия — это сеанс связи между клиентом и сервером, устанавливаемый на определенное время. Сеанс устанавливается непосредственно между клиентом и веб-сервером в момент получения первого запроса к веб-приложению. Каждый клиент устанавливает с сервером свой собственный сеанс, который сохраняется до окончания работы с приложением.
👉 @java_geek
Сессия — это сеанс связи между клиентом и сервером, устанавливаемый на определенное время. Сеанс устанавливается непосредственно между клиентом и веб-сервером в момент получения первого запроса к веб-приложению. Каждый клиент устанавливает с сервером свой собственный сеанс, который сохраняется до окончания работы с приложением.
👉 @java_geek
👍3❤1
Блиц-опрос Scala-разработчиков — самые полезные и бесполезные вещи в работе
Смотрите подкаст «Криптонит говорит» о Scala! В нём айтишники обсуждают:
🔹Scala, Java и их перспективы;
🔹как успешно пройти собеседование в айти;
🔹что нужно делать, чтобы стать хорошим программистом;
🔹и когда нейросети смогут делать code review на уровне старшего разработчика и многое другое.
📺 VK Видео
📺 YouTube
📺 Rutube
💬 Подкаст в телеграме
🎵 Яндекс.Музыка
Смотрите и подписывайтесь на подкаст «Криптонит говорит» — обсуждаем айти, искусственный интеллект, языки программирования и криптографию.
Реклама АО НПК «Криптонит» ИНН 9701115253, erid: 2VtzqveAsgd
Смотрите подкаст «Криптонит говорит» о Scala! В нём айтишники обсуждают:
🔹Scala, Java и их перспективы;
🔹как успешно пройти собеседование в айти;
🔹что нужно делать, чтобы стать хорошим программистом;
🔹и когда нейросети смогут делать code review на уровне старшего разработчика и многое другое.
📺 VK Видео
📺 YouTube
📺 Rutube
💬 Подкаст в телеграме
🎵 Яндекс.Музыка
Смотрите и подписывайтесь на подкаст «Криптонит говорит» — обсуждаем айти, искусственный интеллект, языки программирования и криптографию.
Реклама АО НПК «Криптонит» ИНН 9701115253, erid: 2VtzqveAsgd
О чем говорит ключевое слово throws?
Ответ:
Модификатор throws прописывается в заголовке метода и указывает на то, что метод потенциально может выбросить исключение с указанным типом.
👉 @java_geek
Ответ:
Модификатор throws прописывается в заголовке метода и указывает на то, что метод потенциально может выбросить исключение с указанным типом.
👉 @java_geek
👍2❤1
Что не так с кодом?
Он не скомпилируется. Это вопрос на знание иерархии исключений: FileNotFoundException унаследован от IOException, первый catch будет перехватывать все исключения, а в следующий блок catch управление передано не будет. Поэтому возникнет ошибка: exception FileNotFoundException has already been caught.
👉 @java_geek
Он не скомпилируется. Это вопрос на знание иерархии исключений: FileNotFoundException унаследован от IOException, первый catch будет перехватывать все исключения, а в следующий блок catch управление передано не будет. Поэтому возникнет ошибка: exception FileNotFoundException has already been caught.
👉 @java_geek
👍1
3 декабря(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤1
Что такое пул строк? Это набор строк, хранящийся в Heap.
☕ Пул строк возможен благодаря неизменяемости строк в Java и реализации идеи интернирования строк;
☕ Пул строк помогает экономить память, но по этой же причине создание строки занимает больше времени;
☕ Когда для создания строки используются ", то сначала ищется строка в пуле с таким же значением, если находится, то просто возвращается ссылка, иначе создается новая строка в пуле, а затем возвращается ссылка на неё;
☕ При использовании оператора new создаётся новый объект String. Затем при помощи метода intern() эту строку можно поместить в пул или же получить из пула ссылку на другой объект String с таким же значением;
☕ Пул строк является примером паттерна «Приспособленец» (Flyweight).
👉 @java_geek
☕ Пул строк возможен благодаря неизменяемости строк в Java и реализации идеи интернирования строк;
☕ Пул строк помогает экономить память, но по этой же причине создание строки занимает больше времени;
☕ Когда для создания строки используются ", то сначала ищется строка в пуле с таким же значением, если находится, то просто возвращается ссылка, иначе создается новая строка в пуле, а затем возвращается ссылка на неё;
☕ При использовании оператора new создаётся новый объект String. Затем при помощи метода intern() эту строку можно поместить в пул или же получить из пула ссылку на другой объект String с таким же значением;
☕ Пул строк является примером паттерна «Приспособленец» (Flyweight).
👉 @java_geek
👍3❤2
🚀 Hibernate: Эффективное обновление с
Часто ли вы задумывались, почему Hibernate при обновлении одного поля в сущности генерирует SQL-запрос, который включает все поля? Это может быть неэффективно, особенно для сущностей с десятками колонок.
Именно здесь на помощь приходит аннотация
💡 В чем проблема? (Без
По умолчанию, когда вы вызываете
Если изменилось только
✨ Решение:
Если вы добавите
Смотрим на код:
Сгенерированный SQL:
⚖️ Когда использовать?
- Используйте, если у вас большие сущности (много колонок) и вы часто обновляете только небольшую часть полей. Это сэкономит трафик и немного ускорит базу данных.
- Имейте в виду, что Hibernate придется динамически строить SQL-запрос при каждом обновлении, что может добавить небольшой оверхед, но обычно выгода от оптимизации SQL его перевешивает.
Сделайте ваш код более чистым и эффективным! 🛠️
❓ А вы используете
P.S. Не путайте с
👉 @java_geek
@DynamicUpdateЧасто ли вы задумывались, почему Hibernate при обновлении одного поля в сущности генерирует SQL-запрос, который включает все поля? Это может быть неэффективно, особенно для сущностей с десятками колонок.
Именно здесь на помощь приходит аннотация
@DynamicUpdate!💡 В чем проблема? (Без
@DynamicUpdate)По умолчанию, когда вы вызываете
repository.save(entity) для существующей сущности, Hibernate генерирует UPDATE запрос, который устанавливает значения для всех полей, кроме первичного ключа.
// Without @DynamicUpdate
update employee
set
age=?, // даже если только age изменился
first_name=?, //... и это тоже
last_name=?
where
id=?
Если изменилось только
age, остальные поля обновляются на те же значения, что были.✨ Решение:
@DynamicUpdate(true)Если вы добавите
@DynamicUpdate к вашей сущности, Hibernate будет генерировать SQL-запрос UPDATE, который включает только те поля, которые были изменены (dirty-checking) с момента загрузки или создания сущности.Смотрим на код:
@Entity
@DynamicUpdate // ✨ Добавляем эту аннотацию!
public class Employee extends AbstractPersistable<Long> {
@Column
String firstName;
@Column
String lastName;
@Column
Integer age;
// ...
}
// В EmployeeService:
// var entity = employeeRepository.findById(1L).get();
// entity.setAge(22); // Изменили только возраст
// employeeRepository.save(entity);
Сгенерированный SQL:
// With @DynamicUpdate
update employee
set
age=? // ✅ Обновляется ТОЛЬКО измененное поле
where
id=?
⚖️ Когда использовать?
- Используйте, если у вас большие сущности (много колонок) и вы часто обновляете только небольшую часть полей. Это сэкономит трафик и немного ускорит базу данных.
- Имейте в виду, что Hibernate придется динамически строить SQL-запрос при каждом обновлении, что может добавить небольшой оверхед, но обычно выгода от оптимизации SQL его перевешивает.
Сделайте ваш код более чистым и эффективным! 🛠️
❓ А вы используете
@DynamicUpdate в своих проектах? Поделитесь в комментариях! 👇P.S. Не путайте с
@DynamicInsert, который делает то же самое для INSERT запросов (включает только не-null поля).👉 @java_geek
🔥7❤2
17 декабря(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
☕️ Лямбды и Функциональные интерфейсы: Как это работает под капотом?
Мы все любим лямбды в Java за краткость. Но задумывались ли вы, как строго типизированная Java понимает запись
Все дело в Функциональных интерфейсах. Давайте разберем механику, которая превращает "бойлерплейт" в элегантный код.
🧩 Что такое SAM?
В основе лежит концепция SAM (Single Abstract Method). Функциональный интерфейс - это интерфейс, у которого есть ровно один абстрактный метод.
Лямбда-выражение - это не самостоятельный объект. Это ленивая реализация этого самого единственного метода "на лету".
🔥 До vs После
Взгляните, как функциональный интерфейс
⚙️ Магия
Многие думают, что лямбда - это просто "сахар" для анонимных классов. Это не так!
💜 Анонимный класс создает реальный
💜 Лямбда использует инструкцию байт-кода
👉 Итог: Меньше мусора в памяти и быстрее загрузка приложения.
📚 Шпаргалка: "Великолепная четверка"
В
1.
💜 Суть: Проверка условия (фильтры).
💜 Пример:
2.
💜 Суть: Потребитель. Что-то делает с объектом, ничего не возвращая.
💜 Пример:
3. Function<T, R> ➜
💜 Суть: Преобразователь. Берет T, возвращает R.
💜 Пример:
4.
💜 Суть: Поставщик. Ничего не принимает, отдает объект.
💜 Пример:
💡Всегда ставьте аннотацию
👉 @java_geek
Мы все любим лямбды в Java за краткость. Но задумывались ли вы, как строго типизированная Java понимает запись
x -> x * 2, не зная типа переменной x?Все дело в Функциональных интерфейсах. Давайте разберем механику, которая превращает "бойлерплейт" в элегантный код.
🧩 Что такое SAM?
В основе лежит концепция SAM (Single Abstract Method). Функциональный интерфейс - это интерфейс, у которого есть ровно один абстрактный метод.
Лямбда-выражение - это не самостоятельный объект. Это ленивая реализация этого самого единственного метода "на лету".
🔥 До vs После
Взгляните, как функциональный интерфейс
Predicate<T> убивает лишний шум:
// ❌ До Java 8 (Анонимный класс)
// Куча лишнего кода ради одной проверки
Predicate<String> isLong = new Predicate<String>() {
@Override
public boolean test(String s) {
return s.length() > 5;
}
};
// ✅ С Лямбдой
// Компилятор видит Predicate -> ищет метод test -> подставляет логику
Predicate<String> isLong = s -> s.length() > 5;
⚙️ Магия
invokedynamicМногие думают, что лямбда - это просто "сахар" для анонимных классов. Это не так!
.class файл на диске при компиляции.invokedynamic. Она связывает метод динамически только когда это нужно.👉 Итог: Меньше мусора в памяти и быстрее загрузка приложения.
📚 Шпаргалка: "Великолепная четверка"
В
java.util.function есть интерфейсы на все случаи жизни. Запомните базу:1.
Predicate<T> ➜ booleanstream().filter(x -> x > 0)2.
Consumer<T> ➜ voidlist.forEach(System.out::println)3. Function<T, R> ➜
Rstream().map(User::getName)4.
Supplier<T> ➜ TOptional.orElseGet(() -> new User())💡Всегда ставьте аннотацию
@FunctionalInterface над своими интерфейсами. Это защитит от случайного добавления второго абстрактного метода, который сломает все лямбды в проекте.👉 @java_geek
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥6❤3
24 декабря(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
📂 Сергей Чамкин, старший разработчик из Uzum, ex-WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Cергей будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Сергею
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
📌 Декоратор в Java: Как добавить логику без изменения кода?
🔹 Когда использовать?
- Когда нужно добавить поведение к объекту динамически.
- Когда нельзя или не хочется менять исходный код класса.
- Когда необходимо сохранить принцип открытости/закрытости (OCP из SOLID).
🔹 Как это работает?
Декоратор — это обёртка вокруг базового объекта. Он реализует тот же интерфейс, но внутри может добавлять новую логику.
✅ Пример использования
Допустим, у нас есть базовый интерфейс
И его простая реализация:
Теперь добавим декораторы, которые расширяют функциональность:
1️⃣ Декоратор для отправки в Slack:
2️⃣ Декоратор для отправки в Email:
🚀 Использование:
🔥 Что произойдет?
🎯 Итог:
✅ Мы не изменяли код
✅ Гибкость: можем легко комбинировать декораторы в любом порядке.
✅ Код остаётся чистым и расширяемым.
👉 @java_geek
🔹 Когда использовать?
- Когда нужно добавить поведение к объекту динамически.
- Когда нельзя или не хочется менять исходный код класса.
- Когда необходимо сохранить принцип открытости/закрытости (OCP из SOLID).
🔹 Как это работает?
Декоратор — это обёртка вокруг базового объекта. Он реализует тот же интерфейс, но внутри может добавлять новую логику.
✅ Пример использования
Допустим, у нас есть базовый интерфейс
Notifier, который отправляет уведомления:
public interface Notifier {
void send(String message);
}
И его простая реализация:
public class BasicNotifier implements Notifier {
@Override
public void send(String message) {
System.out.println("Отправка сообщения: " + message);
}
}
Теперь добавим декораторы, которые расширяют функциональность:
1️⃣ Декоратор для отправки в Slack:
public class SlackNotifierDecorator implements Notifier {
private final Notifier wrapped;
public SlackNotifierDecorator(Notifier wrapped) {
this.wrapped = wrapped;
}
@Override
public void send(String message) {
wrapped.send(message); // вызываем базовый метод
System.out.println("Дополнительно отправляем в Slack: " + message);
}
}
2️⃣ Декоратор для отправки в Email:
public class EmailNotifierDecorator implements Notifier {
private final Notifier wrapped;
public EmailNotifierDecorator(Notifier wrapped) {
this.wrapped = wrapped;
}
@Override
public void send(String message) {
wrapped.send(message);
System.out.println("Дополнительно отправляем Email: " + message);
}
}
🚀 Использование:
public class Main {
public static void main(String[] args) {
Notifier notifier = new BasicNotifier();
notifier = new SlackNotifierDecorator(notifier);
notifier = new EmailNotifierDecorator(notifier);
notifier.send("Привет, мир!");
}
}
🔥 Что произойдет?
Отправка сообщения: Привет, мир!
Дополнительно отправляем в Slack: Привет, мир!
Дополнительно отправляем Email: Привет, мир!
🎯 Итог:
✅ Мы не изменяли код
BasicNotifier, но добавили новую функциональность. ✅ Гибкость: можем легко комбинировать декораторы в любом порядке.
✅ Код остаётся чистым и расширяемым.
👉 @java_geek
❤4👍2👏2🔥1
☕️ Java Tips: Инициализация карты в одну строку с
Помните, как раньше приходилось создавать Map с заранее известными значениями? Куча вызовов
Разберем, как это работает и, главное, чего нельзя делать.
🆚 До и После
Как было раньше (The Old Way):
Как сейчас (The Modern Way):
⚠️ Важные нюансы (Gotchas)
Использование
1. Нельзя менять данные
Попытка добавить или удалить элемент приведет к ошибке.
2. Никаких
В отличие от
3. Лимит в 10 пар
Метод
🚀 Когда использовать?
Идеально подходит для конфигураций, статических словарей, тестовых данных и справочников, которые не меняются во время работы программы.
#Java #CodeTips #Programming #Java9
👉 @java_geek
Map.of()Помните, как раньше приходилось создавать Map с заранее известными значениями? Куча вызовов
.put(), статические блоки или (не дай бог) двойные фигурные скобки. Начиная с Java 9, у нас есть красивый и лаконичный способ - Map.of().Разберем, как это работает и, главное, чего нельзя делать.
🆚 До и После
Как было раньше (The Old Way):
Map<String, Integer> map = new HashMap<>();
map.put("One", 1);
map.put("Two", 2);
map.put("Three", 3);
// Результат: много строк кода ради простых данных
Как сейчас (The Modern Way):
Map<String, Integer> map = Map.of(
"One", 1,
"Two", 2,
"Three", 3
);
// Результат: чисто, читаемо, одна инструкция
⚠️ Важные нюансы (Gotchas)
Использование
Map.of() - это не просто синтаксический сахар для HashMap. Это создание неизменяемой (Immutable) структуры.1. Нельзя менять данные
Попытка добавить или удалить элемент приведет к ошибке.
var colors = Map.of("Red", "#FF0000");
colors.put("Blue", "#0000FF");
// ❌ Ошибка: UnsupportedOperationException
2. Никаких
nullВ отличие от
HashMap, здесь нельзя использовать null ни в ключах, ни в значениях.
Map.of("Key", null);
// ❌ Ошибка: NullPointerException
3. Лимит в 10 пар
Метод
Map.of() перегружен для приема до 10 пар ключ-значение. Если нужно больше, используйте Map.ofEntries():
Map.ofEntries(
Map.entry("k1", "v1"),
Map.entry("k2", "v2"),
// ... хоть 100 пар
Map.entry("k100", "v100")
);
🚀 Когда использовать?
Идеально подходит для конфигураций, статических словарей, тестовых данных и справочников, которые не меняются во время работы программы.
#Java #CodeTips #Programming #Java9
👉 @java_geek
👍4❤1🤡1
21 января(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
📂 Сергей Чамкин, старший разработчик из Uzum, ex-WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Cергей будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Сергею
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
⚔️ Java Battle:
На код-ревью часто можно увидеть, как эти два метода используют взаимозаменяемо. На первый взгляд, результат один - список элементов. Но под капотом это два совершенно разных зверя.
Давайте разберем, почему замена одного на другой может сломать ваш код.
1. Иллюзия неизменяемости (The Mutability Trap)
Это самое важное различие.
🔴
🔴
2. Отношение к
🔴
🔴
3. Связь с исходным массивом (Reference vs Copy)
Если вы создаете список из существующего массива:
🏁 Итог
🔴 Используйте
🔴 Используйте
#Java #CodeTips #InterviewQuestions #JavaCore
👉 @java_geek
List.of() vs Arrays.asList() - в чем разница?На код-ревью часто можно увидеть, как эти два метода используют взаимозаменяемо. На первый взгляд, результат один - список элементов. Но под капотом это два совершенно разных зверя.
Давайте разберем, почему замена одного на другой может сломать ваш код.
1. Иллюзия неизменяемости (The Mutability Trap)
Это самое важное различие.
List.of() (Java 9+): Создает по-настоящему неизменяемый список. Вы не можете ни добавить, ни удалить, ни изменить элемент.Arrays.asList() (Java 1.2+): Создает список фиксированного размера, который "обернут" вокруг массива. Вы не можете менять размер (add/remove), но можете заменять элементы!
var legacyList = Arrays.asList("A", "B");
var modernList = List.of("A", "B");
legacyList.set(0, "C"); // ✅ РАБОТАЕТ! Список теперь ["C", "B"]
modernList.set(0, "C"); // ❌ Ошибка: UnsupportedOperationException
legacyList.add("D"); // ❌ Ошибка (размер фиксирован)
modernList.add("D"); // ❌ Ошибка (полная иммутабельность)
2. Отношение к
nullArrays.asList: Разрешает null элементы.List.of: Враждебен к null. Если попытаетесь передать null, мгновенно получите NullPointerException. Это сделано специально, чтобы избежать ошибок в логике.3. Связь с исходным массивом (Reference vs Copy)
Если вы создаете список из существующего массива:
String[] arr = {"One", "Two"};
var list1 = Arrays.asList(arr);
var list2 = List.of(arr);
arr[0] = "Zero"; // Меняем исходный массив
System.out.println(list1); // ["Zero", "Two"] <- Изменился вслед за массивом!
System.out.println(list2); // ["One", "Two"] <- Остался прежним
Arrays.asList работает как "окно" (view) в массив. List.of создает защитную копию данных.🏁 Итог
List.of() в 99% случаев. Это безопаснее, быстрее и потребляет меньше памяти.Arrays.asList(), только если вам нужны null-ы или вы намеренно хотите, чтобы изменения в исходном массиве отражались в списке (редкий кейс).#Java #CodeTips #InterviewQuestions #JavaCore
👉 @java_geek
Please open Telegram to view this post
VIEW IN TELEGRAM
❤5👍2
🕵️ Java
С выходом Java 10 ключевое слово
Но иногда его догадки могут вас удивить. Вот 3 примера, где
1. Ловушка "Diamond Operator" (
Самая частая ошибка новичков.
В чем проблема?
У компилятора нет информации о типе. Он видит пустые скобки
В итоге вы теряете типизацию:
✅ Как исправить:
Если используете
2. Магия "Пересечения типов" (Intersection Types)
А вот это уже высший пилотаж, который часто встречается при использовании
Что будет, если сложить в список данные разных типов?
На самом деле компилятор выведет наиболее специфичный общий тип.
Тип переменной
Java находит общие интерфейсы для
3. Анонимные классы на стероидах
Если бы мы написали
🧠 Золотое правило использования
🔴 👍
🔴 👍
🔴 👎
Читаемость кода важнее краткости!
#Java #CleanCode #Var #Java10
👉 @java_geek
var: Удобный сахар или скрытая угроза?С выходом Java 10 ключевое слово
var позволило нам писать меньше кода. var - это Local Variable Type Inference. Это значит, что Java осталась строго типизированным языком, просто теперь компилятор сам догадывается о типе переменной, глядя на то, что находится справа от знака равно (=).Но иногда его догадки могут вас удивить. Вот 3 примера, где
var работает неочевидно.1. Ловушка "Diamond Operator" (
<>)Самая частая ошибка новичков.
// Без var (Классика)
List<String> list = new ArrayList<>();
// Компилятор видит слева List<String> и понимает, что справа тоже String.
// С var (Ошибка)
var list = new ArrayList<>();
В чем проблема?
У компилятора нет информации о типе. Он видит пустые скобки
<> и решает, что это ArrayList<Object>.В итоге вы теряете типизацию:
list.add("Hello");
list.add(123); // ✅ Это сработает, хотя вы, вероятно, хотели только строки!
✅ Как исправить:
Если используете
var с конструктором, всегда указывайте тип справа:
var list = new ArrayList<String>();
2. Магия "Пересечения типов" (Intersection Types)
А вот это уже высший пилотаж, который часто встречается при использовании
List.of() или Map.of().Что будет, если сложить в список данные разных типов?
var magicList = List.of(10, 20.5, "30");
// Какой тут тип списка? List<Object>?
На самом деле компилятор выведет наиболее специфичный общий тип.
Тип переменной
magicList будет выглядеть примерно так:List<? extends Serializable & Comparable<? extends Serializable & Comparable<?>>>Java находит общие интерфейсы для
Integer, Double и String (все они реализуют Serializable и Comparable) и создает этот ужасный тип-франкенштейн. Это работает, но может свести с ума вашу IDE или методы, принимающие конкретные типы.3. Анонимные классы на стероидах
var позволяет делать трюк, невозможный ранее: сохранять тип анонимного класса.
var user = new Object() {
String name = "Alex";
int age = 25;
};
// Это работает!
System.out.println(user.name);
System.out.println(user.age);
Если бы мы написали
Object user = ..., поля name и age были бы недоступны. А var "видит" реальную структуру анонимного объекта. Это иногда полезно для локальных промежуточных вычислений, заменяя DTO или кортежи.🧠 Золотое правило использования
var хорош тогда, когда тип очевиден из правой части:var users = Map.of("id", 1); (Понятно, что это Map)var stream = list.stream(); (Понятно, что Stream)var result = service.process(); (Что вернулось? boolean? User? null?)Читаемость кода важнее краткости!
#Java #CleanCode #Var #Java10
👉 @java_geek
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4❤1👍1