Как реализовать двусторонний обмен данными между потоками?
Вопрос, который зачастую дается в виде практической задачи. Конечно, результата можно добиться разными способами: парой атомарных переменных, критическими секциями, потокобезопасными коллекциями. Но полезно знать, что специально для этого случая в стандартной библиотеке java.util.concurrent есть простой класс Exchanger.
Класс содержит единственный метод V exchange(V x). Один поток передает в него данные, и встает в ожидание. Ожидание завершается, когда второй поток также приходит в метод exchange со своей порцией информации. В качестве результата вызова потоки получают данные друг друга.
На основе класса Exchanger удобно создавать пайплайны обработки данных. Первый поток выполняет свою часть обработки, и складывает результаты в буфер. В качестве буфера может работать любой многоразовый объект-контейнер. Когда он заполняется, следующий поток обменивает его на второй, пустой буфер. Таким образом два буфера используются поочередно, не выделяется лишний раз память и не нагружается GC. Далее из попарно обменивающихся буферами потоков может строиться длинная многопоточная цепочка обработки.
Вопрос, который зачастую дается в виде практической задачи. Конечно, результата можно добиться разными способами: парой атомарных переменных, критическими секциями, потокобезопасными коллекциями. Но полезно знать, что специально для этого случая в стандартной библиотеке java.util.concurrent есть простой класс Exchanger.
Класс содержит единственный метод V exchange(V x). Один поток передает в него данные, и встает в ожидание. Ожидание завершается, когда второй поток также приходит в метод exchange со своей порцией информации. В качестве результата вызова потоки получают данные друг друга.
На основе класса Exchanger удобно создавать пайплайны обработки данных. Первый поток выполняет свою часть обработки, и складывает результаты в буфер. В качестве буфера может работать любой многоразовый объект-контейнер. Когда он заполняется, следующий поток обменивает его на второй, пустой буфер. Таким образом два буфера используются поочередно, не выделяется лишний раз память и не нагружается GC. Далее из попарно обменивающихся буферами потоков может строиться длинная многопоточная цепочка обработки.
🔥11👍7❤3
Только не в нашем формате!
Ждём вас на открытом практическом уроке от OTUS, где мы:
- установим все, что необходимо для программирования на языке Java;
- изучим несколько базовых блоков, из которых строятся любые приложения;
- на практике посмотрим, как создаются программы на языке Java на примере простой консольной игры.
Спикер Александр Фисунов — Senior Kotlin Developer в SSP Software на проекте ВТБ, опытный ментор, кандидат технических наук.
Встречаемся 29 мая в 20:00 мск в рамках курса «Специализация Java-разработчик».
Все участники вебинара получат специальную цену на обучение!
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1
Чем отличается final finally finalize?
Тем, что это даже синтаксически разные вещи. Как и вопрос о методах Object, это способ начать разговор.
finalize – метод-финализатор из Object.
final – модификатор, который применяется к переменным, полям, методам и классам. Переменная или поле становится неизменяемым и требует инициализации. Финальный метод нельзя переопределить в наследниках. Финальный класс не может иметь наследников вообще. Используется для создания хорошего API по принципу наименьших привилегий.
Когда в методе используется локальная переменная внешней области видимости, она обязана быть effectively final. В этом случае ключевое слово final необязательно, но значение всё равно не должно меняться.
finally – часть языковой конструкции try-catch-finally.
Любое исключение, выброшенное из блока try переводит исполнение в самый соответствующий ему catch (при наличии). Этим продиктована необходимость располагать блоки catch в строгом порядке, от типа исключения-наследника, к родителю. В случае multicatch тот же порядок должен соблюдаться и внутри одного catch. Больше примеров про порядок.
После выполнится блок finally. Выполняется он в любом случае, было исключение или нет. Типичное использование – освобождение ресурсов, обязательные завершающие действия.
Для требующих финализации классов («ресурсов») добавляется интерфейс AutoCloseable, повторяющийся код блока final выносится в метод close и вызывается неявно в конце try-with-resources. Если в этой конструкции присутствует и явный final, он будет выполнен после.
Тем, что это даже синтаксически разные вещи. Как и вопрос о методах Object, это способ начать разговор.
finalize – метод-финализатор из Object.
final – модификатор, который применяется к переменным, полям, методам и классам. Переменная или поле становится неизменяемым и требует инициализации. Финальный метод нельзя переопределить в наследниках. Финальный класс не может иметь наследников вообще. Используется для создания хорошего API по принципу наименьших привилегий.
Когда в методе используется локальная переменная внешней области видимости, она обязана быть effectively final. В этом случае ключевое слово final необязательно, но значение всё равно не должно меняться.
finally – часть языковой конструкции try-catch-finally.
Любое исключение, выброшенное из блока try переводит исполнение в самый соответствующий ему catch (при наличии). Этим продиктована необходимость располагать блоки catch в строгом порядке, от типа исключения-наследника, к родителю. В случае multicatch тот же порядок должен соблюдаться и внутри одного catch. Больше примеров про порядок.
После выполнится блок finally. Выполняется он в любом случае, было исключение или нет. Типичное использование – освобождение ресурсов, обязательные завершающие действия.
Для требующих финализации классов («ресурсов») добавляется интерфейс AutoCloseable, повторяющийся код блока final выносится в метод close и вызывается неявно в конце try-with-resources. Если в этой конструкции присутствует и явный final, он будет выполнен после.
👍7🔥2
Почему интерактивная разработка на Clojure — это круто?
В Clojure ты можешь запустить программу всего один раз и взаимодействовать с ней на протяжении всего процесса разработки в реальном времени. Хочешь разобраться? Тогда ждем тебя на открытом практическом уроке от OTUS, где мы разберем:
▫️как добавлять новые функции или менять состояние программы;
▫️как «прощупывать» любые данные и пошагово отлаживать код;
▫️как запускать тесты и подключаться к внешним системам.
И всё это не выходя из интерактивной среды разработки REPL!
Встречаемся 30 мая в 20:00 мск в рамках курса «Clojure Developer». Все участники вебинара получат специальную цену на обучение!
➡️ Регистрируйся прямо сейчас, чтобы не пропустить бесплатный урок: https://vk.cc/cx2LFC
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
В Clojure ты можешь запустить программу всего один раз и взаимодействовать с ней на протяжении всего процесса разработки в реальном времени. Хочешь разобраться? Тогда ждем тебя на открытом практическом уроке от OTUS, где мы разберем:
▫️как добавлять новые функции или менять состояние программы;
▫️как «прощупывать» любые данные и пошагово отлаживать код;
▫️как запускать тесты и подключаться к внешним системам.
И всё это не выходя из интерактивной среды разработки REPL!
Встречаемся 30 мая в 20:00 мск в рамках курса «Clojure Developer». Все участники вебинара получат специальную цену на обучение!
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2👏2🔥1
Какие существуют литералы?
Литерал – последовательность символов, обозначающая значение примитивного типа (или строки).
🔘 Целочисленные (Integer). Возможные форматы: 2019, 1__000_000 (с Java 7), 10048L (можно l, но будет путаться с 1), 0xfd12aa, 0b1011101, 07654321.
🔘 С плавающей точкой (floating-point). Возможные форматы: 123.4, 56.7e8, .07, 42F, 1.4D (избыточно, по умолчанию и так double).
🔘 Символы и строки. Символ (char) – в одинарных кавычках: 'R'. Спецсимволы пишутся с бэкслешем: '\n'. Любой символ можно представлять в виде escape-последовательности: '\u00F1'. Строковый литерал – последовательность символов в двойных кавычках: "Blabla". Для символов строки действуют те же правила.
🔘 Логические (boolean). true и false.
🔘 Специальный литерал null.
Все нюансы описаны в официальной документации.
Литерал – последовательность символов, обозначающая значение примитивного типа (или строки).
🔘 Целочисленные (Integer). Возможные форматы: 2019, 1__000_000 (с Java 7), 10048L (можно l, но будет путаться с 1), 0xfd12aa, 0b1011101, 07654321.
🔘 С плавающей точкой (floating-point). Возможные форматы: 123.4, 56.7e8, .07, 42F, 1.4D (избыточно, по умолчанию и так double).
🔘 Символы и строки. Символ (char) – в одинарных кавычках: 'R'. Спецсимволы пишутся с бэкслешем: '\n'. Любой символ можно представлять в виде escape-последовательности: '\u00F1'. Строковый литерал – последовательность символов в двойных кавычках: "Blabla". Для символов строки действуют те же правила.
🔘 Логические (boolean). true и false.
🔘 Специальный литерал null.
Все нюансы описаны в официальной документации.
👍13
This media is not supported in your browser
VIEW IN TELEGRAM
Мечтаешь об успешной карьере в Java-разработке, но не знаешь, с чего начать ❓
Прокачайся бесплатно в ИТ-лагере T1.Дебют!
🌟 Приглашаем студентов и выпускников всей страны в ИТ-лагерь — это новый образовательный интенсив для Java-разработчиков от Холдинга Т1 — крупнейшей ИКТ-компании в России по версии RAEX 2023.
ИТ-лагерь проходит в два этапа: 1 месяц онлайн-обучения и неделя летнего атмосферного офлайн-буткемпа! ☀️
Гибкий формат позволяет совмещать обучение в ИТ-лагере со сдачей сессии или работой.
Финалисты получат сертификат на оплачиваемую стажировку, а лучших выпускников с опытом сразу пригласят в команду Т1.
🗓 Подай заявку до 31 мая
Реклама. ООО "Т1". ИНН 7720484492.
Прокачайся бесплатно в ИТ-лагере T1.Дебют!
🌟 Приглашаем студентов и выпускников всей страны в ИТ-лагерь — это новый образовательный интенсив для Java-разработчиков от Холдинга Т1 — крупнейшей ИКТ-компании в России по версии RAEX 2023.
ИТ-лагерь проходит в два этапа: 1 месяц онлайн-обучения и неделя летнего атмосферного офлайн-буткемпа! ☀️
Гибкий формат позволяет совмещать обучение в ИТ-лагере со сдачей сессии или работой.
Финалисты получат сертификат на оплачиваемую стажировку, а лучших выпускников с опытом сразу пригласят в команду Т1.
🗓 Подай заявку до 31 мая
Реклама. ООО "Т1". ИНН 7720484492.
❤2👍1
Какие бывают модификаторы?
🔘 Модификаторы доступа private, protected, public (рассмотрим подробнее в разделе #Классы)
🔘 Модификаторы для многопоточности synchronized и volatile (подробнее чуть позже)
🔘 static (рассмотрим подробнее в разделе #Классы)
🔘 final
🔘 abstract (рассмотрим подробнее в разделе #Классы)
🔘 native – реализация метода скрыта внутри JVM, нельзя указывать в пользовательском коде
🔘 transient – поле будет пропущено при сериализации
🔘 strictfp – самый экзотический, ограничивает точность вычисления для переменной с плавающей точкой до стандарта IEEE. Нужно для переносимости между платформами.
🔘 Модификаторы доступа private, protected, public (рассмотрим подробнее в разделе #Классы)
🔘 Модификаторы для многопоточности synchronized и volatile (подробнее чуть позже)
🔘 static (рассмотрим подробнее в разделе #Классы)
🔘 final
🔘 abstract (рассмотрим подробнее в разделе #Классы)
🔘 native – реализация метода скрыта внутри JVM, нельзя указывать в пользовательском коде
🔘 transient – поле будет пропущено при сериализации
🔘 strictfp – самый экзотический, ограничивает точность вычисления для переменной с плавающей точкой до стандарта IEEE. Нужно для переносимости между платформами.
🔥7👍2❤1
Кошка говорит «мяу», собака говорит «гав», Java-разработчик говорит «кто-нибудь видел мой энергетик? А то мне еще баги исправлять».
Да, быть разработчиком на Java непросто. Но нет ничего невозможного, если у вас есть желание разобраться и двухнедельный подготовительный курс от Хекслета за 990 рублей.
– 62 онлайн-урока;
– 4 живых вебинара;
– практика с первого дня;
– помощь наставника в закрытом чате.
Нет опыта? Не беда! Как говорят в IT-среде: «А что, если попробовать так?»
И мы тоже говорим вам “Попробуйте”
⏰ Cтарт уже 29 мая!
Да, быть разработчиком на Java непросто. Но нет ничего невозможного, если у вас есть желание разобраться и двухнедельный подготовительный курс от Хекслета за 990 рублей.
– 62 онлайн-урока;
– 4 живых вебинара;
– практика с первого дня;
– помощь наставника в закрытом чате.
Нет опыта? Не беда! Как говорят в IT-среде: «А что, если попробовать так?»
И мы тоже говорим вам “Попробуйте”
⏰ Cтарт уже 29 мая!
👍1🤯1
Чем отличаются checked и unchecked исключения?
Вопрос формулируют по-разному, суть вопроса – объяснение иерархии классов исключений. Подробно описано в документации.
Исключения бывают checked и unchecked. Checked требуется указывать в сигнатуре метода в разделе throws; перехватывать или добавлять в throws в вызывающем его методе. Unchecked можно добавить, но не обязательно, перехватывать не обязательно даже если указана в throws.
🔘 Throwable – базовый класс для всего что может быть использовано с оператором throw и в конструкции try-catch
🔘 RuntimeException – «нормальные» unchecked-исключения
🔘 Error – unchecked исключения, которые означают «серьезные проблемы» приложения. Не должны обрабатываться (хотя технически можно). Теоретически JVM может находиться в невалидном состоянии и не давать больше никаких гарантий
🔘 Exception (кроме RuntimeException) – checked исключения
Вопрос формулируют по-разному, суть вопроса – объяснение иерархии классов исключений. Подробно описано в документации.
Исключения бывают checked и unchecked. Checked требуется указывать в сигнатуре метода в разделе throws; перехватывать или добавлять в throws в вызывающем его методе. Unchecked можно добавить, но не обязательно, перехватывать не обязательно даже если указана в throws.
🔘 Throwable – базовый класс для всего что может быть использовано с оператором throw и в конструкции try-catch
🔘 RuntimeException – «нормальные» unchecked-исключения
🔘 Error – unchecked исключения, которые означают «серьезные проблемы» приложения. Не должны обрабатываться (хотя технически можно). Теоретически JVM может находиться в невалидном состоянии и не давать больше никаких гарантий
🔘 Exception (кроме RuntimeException) – checked исключения
👍11🔥3
Почему интерактивная разработка на Clojure — это круто?
В Clojure ты можешь запустить программу всего один раз и взаимодействовать с ней на протяжении всего процесса разработки в реальном времени. Хочешь разобраться? Тогда ждем тебя на открытом практическом уроке от OTUS, где мы разберем:
▫️как добавлять новые функции или менять состояние программы;
▫️как «прощупывать» любые данные и пошагово отлаживать код;
▫️как запускать тесты и подключаться к внешним системам.
И всё это не выходя из интерактивной среды разработки REPL!
Встречаемся 30 мая в 20:00 мск в рамках курса «Clojure Developer». Все участники вебинара получат специальную цену на обучение!
➡️ Регистрируйся прямо сейчас, чтобы не пропустить бесплатный урок: https://vk.cc/cx2LQj
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
В Clojure ты можешь запустить программу всего один раз и взаимодействовать с ней на протяжении всего процесса разработки в реальном времени. Хочешь разобраться? Тогда ждем тебя на открытом практическом уроке от OTUS, где мы разберем:
▫️как добавлять новые функции или менять состояние программы;
▫️как «прощупывать» любые данные и пошагово отлаживать код;
▫️как запускать тесты и подключаться к внешним системам.
И всё это не выходя из интерактивной среды разработки REPL!
Встречаемся 30 мая в 20:00 мск в рамках курса «Clojure Developer». Все участники вебинара получат специальную цену на обучение!
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4❤2🔥2😁1
Зачем нужно ключевое слово default?
Изначально (с Java 1.5) это слово использовалось для объявления дефолтного значения элементов аннотации.
В Java 8 вместе с лямбдами и стримами появилась острая необходимость дополнить стандартные интерфейсы новыми методами. Никто естественно не собирался ломать обратную совместимость, и было предложено добавить методы по умолчанию.
Теперь добавление ключевого слова default к методу интерфейса позволяет добавить ему тело. Все новые методы старых интерфейсов снабжаются дефолтной реализацией.
В реализации такого метода его дефолтный вариант вызывается тем же синтаксисом, что и внешний класс из вложенного: InterfaceName.super.methodName().
Методы по умолчанию подошли еще на шаг к введению в Java беспроблемной версии множественного наследования – примесям (mixin). Интерфейс не может иметь состояния, поэтому полноценные примеси всё ещё недоступны.
Изначально (с Java 1.5) это слово использовалось для объявления дефолтного значения элементов аннотации.
В Java 8 вместе с лямбдами и стримами появилась острая необходимость дополнить стандартные интерфейсы новыми методами. Никто естественно не собирался ломать обратную совместимость, и было предложено добавить методы по умолчанию.
Теперь добавление ключевого слова default к методу интерфейса позволяет добавить ему тело. Все новые методы старых интерфейсов снабжаются дефолтной реализацией.
В реализации такого метода его дефолтный вариант вызывается тем же синтаксисом, что и внешний класс из вложенного: InterfaceName.super.methodName().
Методы по умолчанию подошли еще на шаг к введению в Java беспроблемной версии множественного наследования – примесям (mixin). Интерфейс не может иметь состояния, поэтому полноценные примеси всё ещё недоступны.
👍11🔥4❤1
Углубленному изучению Java – быть!🤝✨
По многочисленным просьбам мы все-таки запускаем новый поток курса «Углубленное изучение языка Java»!
Курс отличается тем, что рассказывает не только как писать код, используя популярные среды, как IDEA, а позволяет узнать, как именно устроен язык. Вы сможете эффективнее использовать ядро и тонкости языка.
Это авторский курс от Дмитрия Когана, который позволяет подготовиться к сертификации Oracle.
Автор курса прошел сертификацию Oracle, и на основе своего опыта, сделал курс, который позволит вам подготовиться к сертификации без штудирования огромной разрозненной литературы.
На курсе мы будем решать практические задачи, которые будут на экзамене.
📢 Стартуем уже 31 мая!
Оставляйте заявку и присоединяйтесь, пока не началось самое интересное и сложное!👉🏻 https://vk.cc/cx8FvU
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
По многочисленным просьбам мы все-таки запускаем новый поток курса «Углубленное изучение языка Java»!
Курс отличается тем, что рассказывает не только как писать код, используя популярные среды, как IDEA, а позволяет узнать, как именно устроен язык. Вы сможете эффективнее использовать ядро и тонкости языка.
Это авторский курс от Дмитрия Когана, который позволяет подготовиться к сертификации Oracle.
Автор курса прошел сертификацию Oracle, и на основе своего опыта, сделал курс, который позволит вам подготовиться к сертификации без штудирования огромной разрозненной литературы.
На курсе мы будем решать практические задачи, которые будут на экзамене.
📢 Стартуем уже 31 мая!
Оставляйте заявку и присоединяйтесь, пока не началось самое интересное и сложное!👉🏻 https://vk.cc/cx8FvU
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576, www.otus.ru
👍6❤2🔥2
В каком порядке указываются модификаторы?
Правила применения модификаторов поля описаны в JLS 8.3.1:
🔘 Нельзя указывать один модификатор дважды;
🔘 Нельзя использовать несколько модификаторов доступа одновременно.
Порядок указания вообще свободный, но обычно используется следующий:
@Аннотации, доступ,
🔘 Те же требования, что и к полю;
🔘 Совместно с abstract кроме аннотаций можно использовать только protected или public;
🔘 native метод не может использовать strictfp.
И так же не требуется, но рекомендуется использовать такой порядок:
@Аннотации, доступ,
Правила применения модификаторов поля описаны в JLS 8.3.1:
🔘 Нельзя указывать один модификатор дважды;
🔘 Нельзя использовать несколько модификаторов доступа одновременно.
Порядок указания вообще свободный, но обычно используется следующий:
@Аннотации, доступ,
static final transient volatileТребования для модификаторов метода находятся в JLS 8.4.3:
🔘 Те же требования, что и к полю;
🔘 Совместно с abstract кроме аннотаций можно использовать только protected или public;
🔘 native метод не может использовать strictfp.
И так же не требуется, но рекомендуется использовать такой порядок:
@Аннотации, доступ,
abstract static final synchronized native strictfp
👍10🥰3
Пройди тест по Java и проверь свои знания, готов ли ты к обучению на курсе.
Ответишь — пройдешь на продвинутый курс "Java Developer. Professional" от OTUS по специальной цене + получишь доступ к записям открытых уроков курса курса
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4🔥2
Что такое короткое замыкание логического оператора?
Логические операторы || и && лево-ассоциативны, то есть их параметры вычисляются слева направо. Если первое значение оказалось true в || или false в && – конечный результат уже предрешен, он будет тем же. В этом случае происходит так называемое «короткое замыкание» (short-circuiting) – оставшийся второй аргумент не вычисляется за ненадобностью.
Эту особенность иногда удобно эксплуатировать, например для проверки на null в одну строку:
Вдобавок доступен оператор «исключающее или» ^. Он почти никогда не используется для булевых параметров, потому что абсолютно эквивалентен более интуитивно понятному !=. Другие битовые операторы для логических аргументов недоступны.
Логические операторы || и && лево-ассоциативны, то есть их параметры вычисляются слева направо. Если первое значение оказалось true в || или false в && – конечный результат уже предрешен, он будет тем же. В этом случае происходит так называемое «короткое замыкание» (short-circuiting) – оставшийся второй аргумент не вычисляется за ненадобностью.
Эту особенность иногда удобно эксплуатировать, например для проверки на null в одну строку:
return param != null && param.getBoolMember();Но иногда такая ситуация влечет за собой неожиданные плавающие баги, если второй аргумент – не переменная, а функция с побочным эффектом. Для этой ситуации введены версии операторов без короткого замыкания: | и &. Это логические вариации «битового и» и «битового или».
Вдобавок доступен оператор «исключающее или» ^. Он почти никогда не используется для булевых параметров, потому что абсолютно эквивалентен более интуитивно понятному !=. Другие битовые операторы для логических аргументов недоступны.
👍15❤5😐2
erid: 2RanykdFByS
Тинькофф проведет Java-митап в Петербурге
Встреча пройдет 4 июня в Ленполиграфмаше. Разработчики расскажут:
— про оптимизацию рекомендаций в условиях ограниченных ресурсов;
— вариантах импакт-анализа;
— связи между событиями в космосе и рутиной разработчиков.
После будет нетворкинг.
:calendar: 4 июня, Tinkoff Java Meetup в Петербурге. Не забудьте зарегистрироваться и позвать с собой коллег.
Реклама. АО "Тинькофф Банк", ИНН 7710140679, лицензия ЦБ РФ № 2673
Тинькофф проведет Java-митап в Петербурге
Встреча пройдет 4 июня в Ленполиграфмаше. Разработчики расскажут:
— про оптимизацию рекомендаций в условиях ограниченных ресурсов;
— вариантах импакт-анализа;
— связи между событиями в космосе и рутиной разработчиков.
После будет нетворкинг.
:calendar: 4 июня, Tinkoff Java Meetup в Петербурге. Не забудьте зарегистрироваться и позвать с собой коллег.
Реклама. АО "Тинькофф Банк", ИНН 7710140679, лицензия ЦБ РФ № 2673
👍5🔥2😱1🍌1
Как узнать, является ли A подтипом B?
В Java доступны три способа проверки совместимости типов. Функционально они ничем не отличаются, применяются для разных наборов аргументов. В порядке убывания быстродействия:
instanceof – бинарный оператор, самый быстрый и самый используемый. Если есть экземпляр A и можно указать B явно, выбирать надо его. Если A (точнее тип хранящей экземпляр A переменной) и B не из одной цепочки наследования – экземпляр точно не может быть подтипом B и компиляция упадет с ошибкой inconvertible types.
Class::isInstance – метод принимает параметром объект типа A. Его стоит выбрать, когда экземпляр A в наличии, но B – неизвестный на этапе компиляции тип. То есть, для переменных A a и Class bClass, можем проверить bClass.isInstance(a).
Class::isAssignableFrom – принимает Class<A>. Единственное, что остается, если экземпляра A нет. bClass.isAssignableFrom(aClass).
Есть еще четвертый способ – имея экземпляр типа A привести его к B. Если типы были несовместимы, приведение выбросит ClassCastException. Это во всех смыслах плохой способ, построению логики программы на исключениях нет оправдания. Подробная аргументация описана в Effective Java Item 57.
В Java доступны три способа проверки совместимости типов. Функционально они ничем не отличаются, применяются для разных наборов аргументов. В порядке убывания быстродействия:
instanceof – бинарный оператор, самый быстрый и самый используемый. Если есть экземпляр A и можно указать B явно, выбирать надо его. Если A (точнее тип хранящей экземпляр A переменной) и B не из одной цепочки наследования – экземпляр точно не может быть подтипом B и компиляция упадет с ошибкой inconvertible types.
Class::isInstance – метод принимает параметром объект типа A. Его стоит выбрать, когда экземпляр A в наличии, но B – неизвестный на этапе компиляции тип. То есть, для переменных A a и Class bClass, можем проверить bClass.isInstance(a).
Class::isAssignableFrom – принимает Class<A>. Единственное, что остается, если экземпляра A нет. bClass.isAssignableFrom(aClass).
Есть еще четвертый способ – имея экземпляр типа A привести его к B. Если типы были несовместимы, приведение выбросит ClassCastException. Это во всех смыслах плохой способ, построению логики программы на исключениях нет оправдания. Подробная аргументация описана в Effective Java Item 57.
👍12🔥3
Узнайте на открытом практическом уроке от OTUS, где вы:
— увидите, как создаются программы на Java с использованием Stream API;
— разберетесь, как легко перевести ваш старый код на Stream API;
— сможете попробовать создать похожие приложения и даже улучшить их.
Спикер Роман Вороновский — опытный разработчик и ментор.
Встречаемся 5 июня в 20:00 мск в рамках курса «Специализация Java-разработчик». Все участники вебинара получат специальную цену на обучение!
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
🎉4👍3🔥2
Что такое ковариантность и контравариантность?
Формально, ковариантность/контравариантность типов – это сохранение/обращение порядка наследования для производных типов. Проще говоря, когда у ковариантных сущностей типами-параметрами являются родитель и наследник, они сами становятся как бы родителем и наследником. Контравариантные наоборот, становятся наследником и родителем.
Легче всего осознать эти понятия на примерах:
🔘 Ковариантность: List<Integer> можно присвоить в переменную типа List<? extends Number> (как будто он наследник List<Number>).
🔘 Контравариантность: в качестве параметра метода List<Number>#sort типа Comparator<? super Number> может быть передан Comparator<Object> (как будто он родитель Comparator<Number>)
Отношение типов «можно присвоить» – не совсем наследование, такие типы называются совместимыми (отношение «is a»).
Существует еще одно связанное понятие – инвариантность. Инвариантность – это отсутствие свойств ковариантности и контрвариантности. Дженерики без вайлдкардов инвариантны: List<Number> нельзя положить ни в переменную типа List<Double>, ни в List<Object>.
Массивы ковариантны: в переменную Object[] можно присвоить значение типа String[].
Переопределение методов начиная с Java 5 ковариантно относительно типа результата и типов исключений.
Формально, ковариантность/контравариантность типов – это сохранение/обращение порядка наследования для производных типов. Проще говоря, когда у ковариантных сущностей типами-параметрами являются родитель и наследник, они сами становятся как бы родителем и наследником. Контравариантные наоборот, становятся наследником и родителем.
Легче всего осознать эти понятия на примерах:
🔘 Ковариантность: List<Integer> можно присвоить в переменную типа List<? extends Number> (как будто он наследник List<Number>).
🔘 Контравариантность: в качестве параметра метода List<Number>#sort типа Comparator<? super Number> может быть передан Comparator<Object> (как будто он родитель Comparator<Number>)
Отношение типов «можно присвоить» – не совсем наследование, такие типы называются совместимыми (отношение «is a»).
Существует еще одно связанное понятие – инвариантность. Инвариантность – это отсутствие свойств ковариантности и контрвариантности. Дженерики без вайлдкардов инвариантны: List<Number> нельзя положить ни в переменную типа List<Double>, ни в List<Object>.
Массивы ковариантны: в переменную Object[] можно присвоить значение типа String[].
Переопределение методов начиная с Java 5 ковариантно относительно типа результата и типов исключений.
🔥9👍6😱1
This media is not supported in your browser
VIEW IN TELEGRAM
Устроиться бэкендером в Яндекс за выходные
8–9 июня устраиваем Weekend Offer Backend. До 6 июня решите задачи в Контесте, 8-го пройдите два собеседования, а 9 июня познакомьтесь с командами и получите офер.
В мероприятии участвуют команды: Crowd, Ecom-сценарии, Поиск, Алиса, Автономные автомобили, Большие данные. Вы сможете пообщаться с менеджерами и выбрать проект, который покажется самым интересным.
Нанимаем в офисы России и Республики Беларусь.
Узнать подробности и зарегистрироваться можно здесь.
Реклама. ООО "Яндекс". ИНН 7736207543
8–9 июня устраиваем Weekend Offer Backend. До 6 июня решите задачи в Контесте, 8-го пройдите два собеседования, а 9 июня познакомьтесь с командами и получите офер.
В мероприятии участвуют команды: Crowd, Ecom-сценарии, Поиск, Алиса, Автономные автомобили, Большие данные. Вы сможете пообщаться с менеджерами и выбрать проект, который покажется самым интересным.
Нанимаем в офисы России и Республики Беларусь.
Узнать подробности и зарегистрироваться можно здесь.
Реклама. ООО "Яндекс". ИНН 7736207543
👍6🔥3🌭1
Разработчик бизнес-приложений на Java
KAMAJI — непрерывно работающий внутренний сервис Яндекса, который позволяет пользователям корпоративной учётной системы OEBS просматривать, создавать и редактировать основные данные в системе (поставщики, заказчики, внутренние счета и пр.). Пользователи работают с данными через UI. Система подсказывает, проверяет и дозаполняет запросы (в том числе с помощью внешних источников из интернета), проводит их через воркфлоу согласования, записывает данные в OEBS и другие системы. KAMAJI — многорукий сервис, который подкидывает топливо основных данных в OEBS для использования в учётных операциях.
Какие задачи вас ждут
– Создание и поддержка микросервисов
Стараемся использовать самые современные технологии и стек: Java 17–22, Spring 3, PostgreSQL 15 и 16.
– Интеграции систем
Используем OpenAPI для описания REST-контрактов, мониторинги, чтобы поддерживать интеграции и сервисы вообще, активно обмениваемся данными с помощью Logbroker и SQS.
– Участие в разных этапах проектов
Наши разработчики участвуют в оценке задач, этапов и даже проектов. Вместе мы занимаемся архитектурным дизайном новых приложений, описываем схемы взаимодействия и разделяем приложения на сервисы. Более опытные разработчики могут стать тимлидами и техлидами проектов. Мы стремимся развивать всех членов команды, учитываем их пожелания: куда и как они хотят расти.
Мы ждём, что вы
– Программируете на Java (Spring, Spring Boot, Spring Security)
– Знаете SQL и работали с реляционными БД
– Работали с Docker и Linux
– Аккуратны и внимательны к деталям
– Умеете тестировать свой код и пишете юнит-тесты
– Готовы самостоятельно прорабатывать технические и архитектурные решения
Откликнуться
KAMAJI — непрерывно работающий внутренний сервис Яндекса, который позволяет пользователям корпоративной учётной системы OEBS просматривать, создавать и редактировать основные данные в системе (поставщики, заказчики, внутренние счета и пр.). Пользователи работают с данными через UI. Система подсказывает, проверяет и дозаполняет запросы (в том числе с помощью внешних источников из интернета), проводит их через воркфлоу согласования, записывает данные в OEBS и другие системы. KAMAJI — многорукий сервис, который подкидывает топливо основных данных в OEBS для использования в учётных операциях.
Какие задачи вас ждут
– Создание и поддержка микросервисов
Стараемся использовать самые современные технологии и стек: Java 17–22, Spring 3, PostgreSQL 15 и 16.
– Интеграции систем
Используем OpenAPI для описания REST-контрактов, мониторинги, чтобы поддерживать интеграции и сервисы вообще, активно обмениваемся данными с помощью Logbroker и SQS.
– Участие в разных этапах проектов
Наши разработчики участвуют в оценке задач, этапов и даже проектов. Вместе мы занимаемся архитектурным дизайном новых приложений, описываем схемы взаимодействия и разделяем приложения на сервисы. Более опытные разработчики могут стать тимлидами и техлидами проектов. Мы стремимся развивать всех членов команды, учитываем их пожелания: куда и как они хотят расти.
Мы ждём, что вы
– Программируете на Java (Spring, Spring Boot, Spring Security)
– Знаете SQL и работали с реляционными БД
– Работали с Docker и Linux
– Аккуратны и внимательны к деталям
– Умеете тестировать свой код и пишете юнит-тесты
– Готовы самостоятельно прорабатывать технические и архитектурные решения
Откликнуться
👍7❤2🔥2