ch
Feedback
Java | Фишки и трюки

Java | Фишки и трюки

前往频道在 Telegram

Java: примеры кода, интересные фишки и полезные трюки Купить рекламу: https://telega.in/c/java_tips_and_tricks ✍️По всем вопросам: @Pascal4eg Менеджер по рекламе: @shmyzna

显示更多
6 960
订阅者
+1024 小时
+457
+7930
吸引订阅者
六月 '26
六月 '26
+55
在0个频道中
五月 '26
+128
在10个频道中
Get PRO
四月 '26
+52
在1个频道中
Get PRO
三月 '26
+51
在8个频道中
Get PRO
二月 '26
+42
在3个频道中
Get PRO
一月 '26
+38
在0个频道中
Get PRO
十二月 '25
+75
在25个频道中
Get PRO
十一月 '25
+108
在11个频道中
Get PRO
十月 '25
+50
在0个频道中
Get PRO
九月 '25
+28
在6个频道中
Get PRO
八月 '25
+187
在24个频道中
Get PRO
七月 '25
+156
在16个频道中
Get PRO
六月 '25
+169
在29个频道中
Get PRO
五月 '25
+221
在32个频道中
Get PRO
四月 '25
+290
在35个频道中
Get PRO
三月 '25
+291
在32个频道中
Get PRO
二月 '25
+1 295
在114个频道中
Get PRO
一月 '25
+292
在14个频道中
Get PRO
十二月 '24
+196
在1个频道中
Get PRO
十一月 '24
+302
在21个频道中
Get PRO
十月 '24
+439
在9个频道中
Get PRO
九月 '24
+226
在1个频道中
Get PRO
八月 '24
+281
在3个频道中
Get PRO
七月 '24
+462
在16个频道中
Get PRO
六月 '24
+229
在1个频道中
Get PRO
五月 '24
+395
在9个频道中
Get PRO
四月 '24
+874
在9个频道中
Get PRO
三月 '24
+408
在6个频道中
Get PRO
二月 '24
+339
在7个频道中
Get PRO
一月 '24
+330
在5个频道中
Get PRO
十二月 '23
+595
在10个频道中
Get PRO
十一月 '23
+663
在12个频道中
Get PRO
十月 '23
+656
在8个频道中
Get PRO
九月 '23
+538
在0个频道中
日期
订阅者增长
提及
频道
04 六月+4
03 六月+11
02 六月+36
01 六月+4
频道帖子
⌨️ Java Concurrency API: Основные классы Современные приложения все чаще требуют выполнения нескольких задач одновременно, и для этого Java предоставляет мощный инструмент — Concurrency API (набор классов и интерфейсов). Этот API позволяет разработчикам легко реализовывать многопоточность, управлять потоками и синхронизировать действия между ними, что значительно увеличивает производительность и отзывчивость приложений. Основные классы: 1. Thread - Класс для создания и управления потоками. Вы можете создать новый поток, реализовав интерфейс Runnable или расширив класс Thread. 2. Executor - Интерфейс для управления потоками и выполнения задач. Позволяет абстрагироваться от управления потоками, сосредоточившись на логике приложения. - ExecutorService: расширение Executor, управляющее жизненным циклом потоков. 3. Future - Позволяет получать результаты из асинхронных задач. Используется в связке с ExecutorService для выполнения задач в фоновом режиме. 4. CountDownLatch - Синхронизирует потоки, позволяя одному или нескольким потокам ждать завершения других потоков перед продолжением работы. 5. CyclicBarrier - Используется для синхронизации группы потоков. Позволяет потоку ждать, пока все другие не достигнут определенной точки. 6. Semaphore - Контролирует доступ к ресурсу, предоставляя определенное количество разрешений для потоков. 7. BlockingQueue - Интерфейс, предоставляющий безопасный способ обмена данными между потоками при помощи очередей. Реализации включают ArrayBlockingQueue, LinkedBlockingQueue и другие. #java #ConcurrencyAPI #Thread

2
Собрали подборку IT-каналов для тех, кто интересуется тестированием, разработкой, автотестами и карьерой в IT. Внутри: QA и A
Собрали подборку IT-каналов для тех, кто интересуется тестированием, разработкой, автотестами и карьерой в IT. Внутри: QA и AQA - практика, собеседования, рабочие заметки и разборы Java и Python - задачи, тесты, полезные фишки и материалы для разработчиков SQL и аналитика данных - запросы, работа с данными и прикладные разборы Программирование и IT-карьера - каналы для тех, кто развивается в профессии и хочет лучше понимать рынок Можно подписаться на всю подборку сразу или выбрать только те каналы, которые подходят под ваши цели. Забрать папку
589
3
⌨️ Desktop Класс Desktop используется для взаимодействия с приложениями операционной системы, такими как веб-браузер, почтовый клиент, просмотрщик изображений и т.д. Этот класс входит в пакет java.awt и позволяет, например, открыть веб-ссылку в браузере или отправить письмо через почтовый клиент. Основные возможности класса Desktop: ✔️ browse(URI uri) – открывает URI (например, веб-страницу) в браузере. ✔️ open(File file) – открывает файл в приложении, ассоциированном с его типом (например, текстовый файл в текстовом редакторе). ✔️ edit(File file) – открывает файл в режиме редактирования (если доступно). ✔️ mail(URI mailtoURI) – открывает почтовое приложение с указанным URI. ✔️ print(File file) – отправляет файл на печать. Пример: import java.awt.*; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; public class DesktopExample { public static void main(String[] args) throws IOException, URISyntaxException { // Проверяем, поддерживает ли система класс Desktop if (Desktop.isDesktopSupported()) { Desktop desktop = Desktop.getDesktop(); // Пример: Открытие веб-страницы URI uri = new URI("http://www.google.com"); desktop.browse(uri); } else { System.out.println("Класс Desktop не поддерживается на этой системе."); } } } Проверка Desktop.isDesktopSupported() обязательна, так как класс может не поддерживаться на некоторых системах. #java #Desktop
855
4
⌨️ Почему Stream.parallel() может сделать код медленнее Когда разработчики впервые видят: list.parallelStream() возникает мысль: О, бесплатная многопоточность 🚀 Но на практике parallelStream() очень часто: ❗ НЕ ускоряет код ❗ делает его медленнее ❗ а иногда ещё и ломает логику 📦 Как это работает list.parallelStream() .map(this::process) .toList(); Java разбивает задачи между потоками через ForkJoinPool.commonPool(). 🔥 Когда это реально помогает ✔️ CPU-heavy вычисления ✔️ большие объёмы данных ✔️ независимые операции Например: ✅ обработка миллионов чисел ✅ сложные математические вычисления ✅ image processing ⚠️ Когда будет хуже ❌ Маленькие коллекции List.of(1, 2, 3) .parallelStream() 👉 накладные расходы на потоки будут больше пользы ❌ I/O операции users.parallelStream() .map(this::callApi) 👉 потоки начинают ждать сеть/БД 👉 ForkJoinPool забивается ❌ Общие mutable-данные List<String> result = new ArrayList<>(); list.parallelStream() .forEach(result::add); 💣 Race condition detected 🙂 ❌ Неочевидный порядок parallelStream().forEach(System.out::println); Порядок вывода будет случайным. 🧠 Самая скрытая проблема parallelStream() использует ОБЩИЙ pool потоков. То есть: ▸ твой код ▸ библиотека ▸ другой модуль приложения могут конкурировать за одни и те же потоки. 👉 Особенно весело в backend-приложениях. 🚀 Иногда обычный stream быстрее Почему? Потому что parallel: ▸ делит задачи ▸ синхронизирует результаты ▸ координирует потоки Это тоже стоит времени. ✅ Хорошее правило Используй parallelStream() только если: ▸ операция тяжёлая ▸ данных много ▸ нет shared mutable state ▸ ты реально измерил performance
1 051
5
⌨️ EnumMap — это реализация Map, которая использует в качестве ключей исключительно Enum. Внутренне EnumMap использует массив для хранения значений, где индекс массива соответствует порядковому номеру (ordinal()) элемента перечисления. Это делает его быстрее, чем хэш-таблицы (HashMap) и более экономным по памяти. EnumMap хранит ключи в порядке их объявления в перечислении, что отличает его от большинства других Map (кроме LinkedHashMap). Так как ключи строго ограничены перечислением, это снижает вероятность ошибок при разработке. 🔍 Пример: import java.util.EnumMap; enum Action { START, STOP, PAUSE } public class EnumMapExample { public static void main(String[] args) { EnumMap<Action, Runnable> actionMap = new EnumMap<>(Action.class); // Определяем поведение для каждого значения Enum actionMap.put(Action.START, () -> System.out.println("Starting the process...")); actionMap.put(Action.STOP, () -> System.out.println("Stopping the process...")); actionMap.put(Action.PAUSE, () -> System.out.println("Pausing the process...")); // Пример вызова Action currentAction = Action.START; actionMap.get(currentAction).run(); } } #Java #EnumMap
1 347
6
👨👨👨👨👨👨👨👨👨👨 Каналы с Junior IT вакансиями и стажировками Подписывайся и забирай свой оффер 🤘 1. Стажировки и ваканс
👨👨👨👨👨👨👨👨👨👨 Каналы с Junior IT вакансиями и стажировками Подписывайся и забирай свой оффер 🤘 1. Стажировки и вакансии по России и миру 2. IT вакансии по СНГ 3. IT стажировки по СНГ 4. ИИ-ассистент для автооткликов 5. IT стажировки и волонтерства 6. IT стажировки в топовых компаниях мира 7. Удалённые IT вакансии и стажировки 8. Python вакансии и стажировки 9. БИГТЕХ вакансии и стажировки 10. Design вакансии и стажировки 11. QA вакансии и стажировки 12. Junior вакансии и стажировки 13. Frontend вакансии и вопросы собесов 14. Вакансии и стажировки для аналитиков 15. Вакансии в русских стартапах за границей 16. Вакансии и стажировки для DevOps 17. Вакансии, которых нет на ХХ.РУ
604
7
⌨️ ThreadLocal - удобство, которое легко превращается в утечку памяти ThreadLocal выглядит как магия: У каждого потока будет своё собственное значение И это правда. Но именно из-за этого он часто становится источником очень неприятных багов в production. 📦 Как работает ThreadLocal ThreadLocal<String> currentUser = new ThreadLocal<>(); currentUser.set("Alex"); Теперь в каждом потоке хранится своё значение: System.out.println(currentUser.get()); 🔥 Где это используют * Spring Security * Hibernate * логирование (`traceId`) * транзакции * хранение request context 🤔 Кажется идеально. В чём проблема? Проблема начинается с thread pool. ⚠️ Главная ловушка ThreadLocal<String> local = new ThreadLocal<>(); executor.submit(() -> { local.set("DATA"); }); Поток из пула НЕ уничтожается после задачи. 👉 Значение остаётся висеть внутри потока. 💣 Что это вызывает * утечки памяти * неожиданные данные между запросами * "рандомные" баги в серверных приложениях 😨 Самое неприятное Даже если сам ThreadLocal удалён GC, значение внутри потока может продолжать жить. Почему? Потому что внутри Thread: * ключ (`ThreadLocal`) хранится как weak reference * а значение - как strong reference 👉 Ключ умер 👉 Значение осталось Классическая hidden memory leak. ✅ Правильный подход ВСЕГДА чистить ThreadLocal: try { local.set("DATA"); // работа } finally { local.remove(); } 🚀 Почему это критично в Spring / Tomcat Сервер использует thread pool: * один поток обслуживает тысячи запросов * забытый ThreadLocal живёт очень долго Отсюда: * рост памяти * странное поведение пользователей * “невоспроизводимые” баги 🧠 Интересный факт ThreadLocal не хранит данные “в себе”. Наоборот: 👉 каждый Thread хранит ThreadLocalMap То есть данные лежат внутри потока, а не объекта ThreadLocal.
1 122
8
👨👨👨👨👨👨👨👨👨👨 Каналы с IT мероприятиями Подписывайся, чтобы не пропустить 🤘 1. IT мероприятия для стажеров и студенто
👨👨👨👨👨👨👨👨👨👨 Каналы с IT мероприятиями Подписывайся, чтобы не пропустить 🤘 1. IT мероприятия для стажеров и студентов 2. IT мероприятия по РФ 3. IT мероприятия и хакатоны 4. Бесплатные IT мероприятия 5. IT мероприятия онлайн 6. IT мероприятия Москва 7. IT мероприятия Санкт-Петербург
643
9
⌨️ Сравнение объектов с помощью Comparator и Comparable В Java для сортировки объектов используются два ключевых интерфейса: Comparable и Comparator. Понимание их отличий и применения поможет вам эффективно управлять сортировкой данных в коллекциях. 📚 Краткие определения: - Comparable: - Используется, когда класс должен иметь естественный порядок. Например, мы можем сортировать людей по возрасту. - Сигнатура метода: int compareTo(T o). Пример: class Person implements Comparable<Person> { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public int getAge() { return age; } @Override public int compareTo(Person other) { return Integer.compare(this.age, other.age); // Сравнение по возрасту } } - Comparator: - Используется для создания внешних стратегий сравнения, позволяя определять несколько способов сортировки. Подходит для сортировки объектов разных классов. - Сигнатура метода: int compare(T o1, T o2). Пример: import java.util.Comparator; class NameComparator implements Comparator<Person> { @Override public int compare(Person p1, Person p2) { return p1.name.compareTo(p2.name); // Сравнение по имени } } ⚖️ Когда использовать: - Comparable: - Используйте, если у класса есть естественный порядок. Например, чтобы сортировать людей по возрасту. - Сортировка с помощью Collections.sort() или Arrays.sort() будет проще. Пример использования: List<Person> people = Arrays.asList(new Person("Alice", 30), new Person("Bob", 25)); Collections.sort(people); // Сортировка по возрасту с использованием Comparable - Comparator: - Идеален для ситуаций, когда необходимо изменить порядок сортировки или сравнивать объекты разных классов. Пример использования: List<Person> people = Arrays.asList(new Person("Alice", 30), new Person("Bob", 25)); Collections.sort(people, new NameComparator()); // Сортировка по имени с использованием Comparator #java #Comparator #Comparable
1 017
10
⌨️ Чем абстрактный класс отличается от интерфейса? В каких случаях следует использовать абстрактный класс, а в каких интерфейс? ✔️ В Java класс может одновременно реализовать несколько интерфейсов, но наследоваться только от одного класса. ✔️ Абстрактные классы используются только тогда, когда присутствует тип отношений «is a» (является). Интерфейсы могут реализоваться классами, которые не связаны друг с другом. ✔️ Абстрактный класс - средство, позволяющее избежать написания повторяющегося кода, инструмент для частичной реализации поведения. Интерфейс - это средство выражения семантики класса, контракт, описывающий возможности. Все методы интерфейса неявно объявляются как public abstract или (начиная с Java 8) default - методами с реализацией по-умолчанию, а поля - public static final. ✔️ Интерфейсы позволяют создавать структуры типов без иерархии. ✔️ Наследуясь от абстрактного, класс «растворяет» собственную индивидуальность. Реализуя интерфейс, он расширяет собственную функциональность. Абстрактные классы содержат частичную реализацию, которая дополняется или расширяется в подклассах. При этом все подклассы схожи между собой в части реализации, унаследованной от абстрактного класса, и отличаются лишь в части собственной реализации абстрактных методов родителя. Поэтому абстрактные классы применяются в случае построения иерархии однотипных, очень похожих друг на друга классов. В этом случае наследование от абстрактного класса, реализующего поведение объекта по умолчанию может быть полезно, так как позволяет избежать написания повторяющегося кода. Во всех остальных случаях лучше использовать интерфейсы. #java #interface #abstract
1 377
11
🔴 Завтра тестовое собеседование с Java-разработчиком 13 мая(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседов
🔴 Завтра тестовое собеседование с Java-разработчиком 13 мая(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика. Как это будет: 📂 Виктор Анохин, старший разработчик из WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу 📂 Виктор будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью 📂 В конце можно будет задать любой вопрос Виктору Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы. Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot Реклама. О рекламодателе.
628
12
🛠 Разница между StringBuilder и StringBuffer И StringBuilder, и StringBuffer используются для работы со строками, но между ними есть важные отличия. ➡️ Основные различия: ✔️ StringBuilder быстрее, но не потокобезопасен. ✔️ StringBuffer потокобезопасен, но медленнее из-за синхронизации. ✔️ Пример использования StringBuilder: StringBuilder sb = new StringBuilder("Hello"); sb.append(" World"); System.out.println(sb); // Hello World ✔️ Пример использования StringBuffer: StringBuffer sb = new StringBuffer("Hello"); sb.append(" World"); System.out.println(sb); // Hello World 💡 Совет: Если ваш код выполняется в одном потоке, используйте StringBuilder для лучшей производительности. #java #stringbuilder #stringbuffer
1 577
13
⚠️ Внимание: Опубликована слитая недавно База из 1000+ топовых курсов и материалов для айтишников Отсортировали их для вашего
⚠️ Внимание: Опубликована слитая недавно База из 1000+ топовых курсов и материалов для айтишников Отсортировали их для вашего удобства и выложили в телеграм-каналы по категориям: 🤖 Нейросети – 855+ материалов 🖥 Python — 1558+ материалов 👩‍💻 Frontend — 1241+ материалов 👩‍💻 Backend — 1095+ материалов ⚙️ Программы — 978+ материалов 📚 Книги по IT — 779+ материалов ⌛️ Ссылки будут активны 48 часов, сохрани себе, чтобы не потерять!
627
14
⌨️ Arrays.deepToString() Метод deepToString из класса Arrays используется для создания строкового представления многомерных массивов (например, массивов массивов). Он обходит каждый уровень вложенности массива и выводит его элементы в виде строки. Это удобно для работы с многомерными массивами, так как стандартный метод toString не раскрывает их структуру. Пример использования: int[][] array = {{1, 2, 3}, {4, 5, 6}}; System.out.println(Arrays.deepToString(array)); // [[1, 2, 3], [4, 5, 6]] Этот метод работает рекурсивно, обеспечивая полное отображение структуры массива любой вложенности. #java #Arrays #deepToString
1 605
15
📌 Что такое volatile и как оно работает? Ключевое слово volatile в Java используется для переменных, к которым обращаются несколько потоков. Оно гарантирует, что изменения переменной одним потоком будут видны другим. ✔️ Основные особенности: 1️⃣ Обеспечивает чтение переменной из основной памяти, а не из кэша потока. 2️⃣ Гарантирует видимость изменений между потоками. Пример: class SharedObject { volatile int count = 0; } 💡 Ограничение: volatile не гарантирует атомарность операций. Для этого используйте synchronized или классы из java.util.concurrent. #java #volatile #multithreading
1 667
16
Изучаете программирование, или хотите стать классным айтишником с высокой ЗП? Пока многие паникуют из-за бума ИИ, вы можете с
Изучаете программирование, или хотите стать классным айтишником с высокой ЗП? Пока многие паникуют из-за бума ИИ, вы можете стремительно войти в сферу IT при помощи сборки "IT в деле" которую мы составили. Специально для вас разбили нашу сборку мини папки по конкретным тематикам:) Что внутри сборки: - Каналы о программировании и разработке: Python, CSS, HTML, Java и Swift - GameDev и каналы о QA тестироварии, создание игр, помощь для ваших проектов и реальный опыт от тестировщиков 💍 - Авторские каналы и вайбкодинг: IT & AI, простые заметки с проектов, работа с нейросетями, и как они реально влияют на индустрию 🔤 - Информационная безопасность: многое узнаете о работе хакеров и о том, как защитить себя в этом интернет-хаосе. 🔫 Для каждого здесь что-то найдётся! Выберите интересные вам каналы или подпишитесь на всю сборку, и найдите то, что нужно вам для следующего шага в IT.
859
17
⌨️ Почему `try-with-resources` это больше, чем "синтаксический сахар" Многие воспринимают try-with-resources как просто удобную замену finally. Но под капотом есть важная деталь, о которой часто забывают - подавленные исключения (suppressed exceptions). 📦 Классический код try { InputStream is = new FileInputStream("file.txt"); // работа с потоком } finally { is.close(); } ❗ Проблема: если в try и в close() произойдут исключения - одно из них потеряется. ✅ try-with-resources try (InputStream is = new FileInputStream("file.txt")) { // работа с потоком } 👉 Java сама закроет ресурс и корректно обработает исключения 🔥 Вот где магия try (MyResource r = new MyResource()) { throw new RuntimeException("Ошибка в try"); } И допустим, close() тоже кидает исключение: @Override public void close() { throw new RuntimeException("Ошибка при закрытии"); } 🤯 Что произойдёт? * Основное исключение: "Ошибка в try" * Исключение из close() НЕ потеряется * Оно попадёт в suppressed exceptions 📌 Как их получить try (MyResource r = new MyResource()) { ... } catch (Exception e) { for (Throwable t : e.getSuppressed()) { t.printStackTrace(); } } ⚠️ Почему это важно Если не знаешь про suppressed exceptions: * можно потерять важную информацию об ошибках * сложнее дебажить ресурсы (файлы, сокеты, DB) 🧠 Кастомные ресурсы Чтобы использовать try-with-resources, класс должен реализовывать AutoCloseable: class MyResource implements AutoCloseable { @Override public void close() { // cleanup } } 👉 Даже свои классы можно встроить в этот механизм 🚀 Маленький лайфхак (Java 9+) Можно объявить ресурс заранее: InputStream is = new FileInputStream("file.txt"); try (is) { // используем } 📌 Вывод try-with-resources это не только удобство, а ещё и правильная модель обработки исключений, которую вручную реализовать сложно.
1 445
18
На Stepik запустили годный курс по «Troubleshooting Docker и Kubernetes: поиск и устранение проблем» В программе только важны
На Stepik запустили годный курс по «Troubleshooting Docker и Kubernetes: поиск и устранение проблем» В программе только важные аспекты: — troubleshooting Docker и образов — диагностика сетевых проблем — настройка readiness/liveness probes — отладка pod’ов, деплоев и ingress — анализ логов контейнеров и кластера — разбор ошибок CrashLoopBackOff, OOMKilled, ImagePullBackOff и других Собеседования на DevOps/SRE сейчас всё чаще строятся вокруг реальных инцидентов. Данный курс фокусируется именно на таких сценариях и помогает в подготовке к практическим вопросам 48 часов доступен со скидкой 25% ↗️ Пройти курс на Stepik
616
19
☕️ Возвращение пустых коллекций вместо null Возвращение пустых коллекций вместо null-это рекомендуемый подход для методов, возвращающих коллекции. Он упрощает обработку данных, предотвращает ошибки и делает код более предсказуемым. ✅ Преимущества 1. Улучшение читаемости: Код становится проще, так как не нужно проверять результат на null. 2. Предотвращение NullPointerException: Исключается вероятность ошибок, связанных с доступом к null. 3.Соответствие принципу наименьшего удивления: Методы всегда возвращают коллекцию, даже если она пуста. 4. Эффективность: Пустые коллекции создаются один раз и переиспользуются благодаря реализации через паттерн Singleton. 5. Совместимость с функциональным программированием: Пустые коллекции легко интегрируются в стримы и другие функциональные конструкции. Пример: public class CacheService {     private final Map<String, List<Object>> cache = new ConcurrentHashMap<>();     public List<Object> getCachedValues(String key) {         return cache.getOrDefault(key, Collections.emptyList());     }     public void addToCache(String key, Object value) {         cache.computeIfAbsent(key, k -> new ArrayList<>()).add(value);     } } ❗️ Метод Collections.emptyList() является частью стандартной библиотеки Java (java.util.Collections). Он реализован через паттерн Singleton для повышения эффективности и безопасности. Использование пустых коллекций вместо null делает код более устойчивым и предсказуемым. Это особенно важно в сложных многопоточных приложениях или системах с большим количеством взаимосвязанных компонентов.
1 264
20
⌨️ Неограниченным wildcard <?> В Java <?> называется неограниченным wildcard. Он обозначает, что параметр типа может быть любым, то есть неизвестным на этапе компиляции. Это удобно, когда метод или класс работают с обобщёнными типами, но конкретный тип элемента не важен. Например, выражение List<?> означает список, элементы которого могут быть любого типа. Такой подход позволяет писать более универсальный и гибкий код, но при этом накладывает ограничения: мы не можем добавлять новые элементы в коллекцию, поскольку компилятор не знает конкретный тип элементов, чтобы обеспечить безопасность типов. ✔️ Прием метода, работающего с любым типом списка import java.util.List; public class WildcardExample { public static void printList(List<?> list) { for (Object element : list) { // Элементы можно читать как Object System.out.println(element); } } public static void main(String[] args) { List<Integer> intList = List.of(1, 2, 3); List<String> strList = List.of("A", "B", "C"); printList(intList); // Вывод: 1 2 3 printList(strList); // Вывод: A B C } } Здесь List<?> позволяет передавать любой тип списка, но мы можем безопасно читать только как Object. ❌ Ограничение на добавление элементов public static void addElement(List<?> list) { // list.add("Hello"); // Ошибка компиляции! } #java #wildcard
1 297