Чем отличаются 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
💡Какие паттерны нужно знать разработчикам?
Один из них — паттерн "Цепочка обязанностей". Именно его мы разберем на открытом уроке в Otus.
На уроке рассмотрим:
— как использовать шаблон для решения различных задач
— покажем, как создать классы обработчиков и связать их в цепочку, чтобы сообщение было обработано последовательно каждым обработчиком
— рассмотрим возможности настройки приоритета и условий обработки определенных сообщений
Встречаемся 03 июня в 20:00 мск в преддверии старта курса «Архитектура и шаблоны проектирования». Все участники вебинара получат специальную цену на обучение и консультацию от менеджеров OTUS!
Регистрируйтесь прямо сейчас, чтобы посетить бесплатный урок: https://vk.cc/cxhYKo
Один из них — паттерн "Цепочка обязанностей". Именно его мы разберем на открытом уроке в Otus.
На уроке рассмотрим:
— как использовать шаблон для решения различных задач
— покажем, как создать классы обработчиков и связать их в цепочку, чтобы сообщение было обработано последовательно каждым обработчиком
— рассмотрим возможности настройки приоритета и условий обработки определенных сообщений
Встречаемся 03 июня в 20:00 мск в преддверии старта курса «Архитектура и шаблоны проектирования». Все участники вебинара получат специальную цену на обучение и консультацию от менеджеров OTUS!
Регистрируйтесь прямо сейчас, чтобы посетить бесплатный урок: https://vk.cc/cxhYKo
👍5🔥2😁2❤1
Как работает вывод типов?
Для начала разберемся, что такое вывод типов. Type inference – это способность компилятора догадаться, какой тип нужно подставить, и сделать это за вас. На обычном интервью никто не спросит детали алгоритма вывода типов, достаточно будет сказать, что вывод происходит статически, только на основании типов аргументов и ожидаемого типа результата. По сути, вопрос заключается не в «как работает?», а «что это и когда возникает?».
Первое, что многим приходит в голову при фразе «вывод типов» – diamond operator <>. Он появился в Java с версии 7. Его применяют к конструкторам дженерик классов, чтобы отличать требование автоматического вывода типа от raw type.
С Java 9 diamond operator заработал и для анонимных классов.
Для дженерик методов можно указывать параметр явно, но diamond синтаксически недопустим – вывод и так сработает по умолчанию.
В Java 10 для вывода типа локальной переменной добавлено ключевое слово var. Работает это так же, как в большинстве современных языков – ключевое слово ставится вместо типа при объявлении.
Типы выводимых параметров лямбда-выражения также можно не указывать. С Java 11 вместо типа указывается ключевое слово var. Такой синтаксис дает возможность добавлять параметру модификаторы и аннотации.
Для начала разберемся, что такое вывод типов. Type inference – это способность компилятора догадаться, какой тип нужно подставить, и сделать это за вас. На обычном интервью никто не спросит детали алгоритма вывода типов, достаточно будет сказать, что вывод происходит статически, только на основании типов аргументов и ожидаемого типа результата. По сути, вопрос заключается не в «как работает?», а «что это и когда возникает?».
Первое, что многим приходит в голову при фразе «вывод типов» – diamond operator <>. Он появился в Java с версии 7. Его применяют к конструкторам дженерик классов, чтобы отличать требование автоматического вывода типа от raw type.
С Java 9 diamond operator заработал и для анонимных классов.
Для дженерик методов можно указывать параметр явно, но diamond синтаксически недопустим – вывод и так сработает по умолчанию.
В Java 10 для вывода типа локальной переменной добавлено ключевое слово var. Работает это так же, как в большинстве современных языков – ключевое слово ставится вместо типа при объявлении.
Типы выводимых параметров лямбда-выражения также можно не указывать. С Java 11 вместо типа указывается ключевое слово var. Такой синтаксис дает возможность добавлять параметру модификаторы и аннотации.
👍10🔥1
Узнайте на открытом практическом уроке «Применение batch-операций в Jdbc» от OTUS. Познакомимся с возможностями инструмента, ответим на все возникающие вопросы.
Спикер Сергей Петрелевич — опытный Java/Kotlin-разработчик, Oracle Certified Professional, Java SE 8 Programmer.
Встречаемся 11 июня в 20:00 мск в рамках курса «Java Developer. Professional».
Все участники вебинара получат специальную цену на обучение!
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤1🔥1
Чем анонимный внутренний класс отличается от лямбды?
Лямбда-выражение имеет более легковесный синтаксис. Не нужно явно указывать тип функционального интерфейса, который лямбда реализует – он автоматически выведется из контекста. Лямбда-выражения добавлены в язык в первую очередь как синтаксический сахар.
С другой стороны, у класса есть поля. Экземпляр анонимного класса сохраняет свое состояние между вызовами, и меняет его при необходимости. Для лямбды доступен лишь захват и effectively final использование внешних переменных.
Лямбдой реализуется только функциональный интерфейс. Функциональный интерфейс – это тип с единственным абстрактным методом. Анонимным классом же можно расширить любой расширяемый класс или реализовать интерфейс с любым количеством абстрактных методов.
Анонимный класс создает новый скоуп, лямбда работает в текущем. Это значит, что объявление переменной с именем, которое уже используется снаружи, в лямбде вызовет ошибку компиляции «variable is already defined», в анонимном классе скроет (shadowing) внешнюю переменную.
С точки зрения реализации JVM, для лямбды не создается дополнительного .class файла, как это происходит для анонимного класса. Соответственно, не происходит и обычной загрузки и верификации класса. Вместо этого используется механизм invokedynamic и класс генерируется на лету с помощью LambdaMetafactory. Так что лямбда-выражения обычно работают быстрее.
Лямбда-выражение имеет более легковесный синтаксис. Не нужно явно указывать тип функционального интерфейса, который лямбда реализует – он автоматически выведется из контекста. Лямбда-выражения добавлены в язык в первую очередь как синтаксический сахар.
С другой стороны, у класса есть поля. Экземпляр анонимного класса сохраняет свое состояние между вызовами, и меняет его при необходимости. Для лямбды доступен лишь захват и effectively final использование внешних переменных.
Лямбдой реализуется только функциональный интерфейс. Функциональный интерфейс – это тип с единственным абстрактным методом. Анонимным классом же можно расширить любой расширяемый класс или реализовать интерфейс с любым количеством абстрактных методов.
Анонимный класс создает новый скоуп, лямбда работает в текущем. Это значит, что объявление переменной с именем, которое уже используется снаружи, в лямбде вызовет ошибку компиляции «variable is already defined», в анонимном классе скроет (shadowing) внешнюю переменную.
С точки зрения реализации JVM, для лямбды не создается дополнительного .class файла, как это происходит для анонимного класса. Соответственно, не происходит и обычной загрузки и верификации класса. Вместо этого используется механизм invokedynamic и класс генерируется на лету с помощью LambdaMetafactory. Так что лямбда-выражения обычно работают быстрее.
👍31🔥2
🎯 Как джуну в Java-разработке миновать мучительные поиски хорошего оффера и залететь сразу на мидла?
Актуальное обучение для всех, кто хочет стать Java-разработчиком с нуля и для тех, кто еще не определился с языком программирования.
📌 После онлайн-курса «Специализация Java-разработчик» от OTUS вы сможете:
- создавать современные приложения на Java;
- работать с реляционными базами данных;
- разрабатывать серверные веб-приложения;
- претендовать на позиции Middle Java Developer.
Вы освоите самые востребованные инструменты и лучшие практики.
Забудьте о скучном обучении — здесь вас ждут настоящие челленджи и нестандартные практические решения. А еще сильные проекты для портфолио и карьерный сапорт!
Старт уже 28 июня.
👉 Изучите подробности и оставьте заявку, чтобы получить специальную цену на курс: https://vk.cc/cxqQAF
Актуальное обучение для всех, кто хочет стать Java-разработчиком с нуля и для тех, кто еще не определился с языком программирования.
- создавать современные приложения на Java;
- работать с реляционными базами данных;
- разрабатывать серверные веб-приложения;
- претендовать на позиции Middle Java Developer.
Вы освоите самые востребованные инструменты и лучшие практики.
Забудьте о скучном обучении — здесь вас ждут настоящие челленджи и нестандартные практические решения. А еще сильные проекты для портфолио и карьерный сапорт!
Старт уже 28 июня.
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
🥰6🤣4👍2🔥2
Как объявить переменное количество аргументов метода?
Для этого используется аргумент-массив. В нем может находиться любое количество элементов. Еще с Java 5 для этого случая добавился синтаксический сахар: Variable-length argument (vararg). Три точки ... ставятся между типом и именем переменной, и становится можно передать любое количество аргументов, не упаковывая их в массив.
На уровне байткода применение массива и варарга не отличаются: vararg-параметр Foo... превращается в параметр-массив Foo[], на этапе вызова подставляется неявное инстанцирование и заполнение массива.
Чтобы избежать неоднозначностей, на vararg наложено ограничение: им может быть только один последний аргумент.
Vararg, как массив, может быть пустым. Иногда это приводит к неочевидному поведению. Допустим, имеем две перегрузки метода с аргументами int... и float.... Вызов такого метода без параметров попадает в вариант с int, как с более специфичным типом. Наличие же перегрузки с несовместимыми типами, например int... и boolean..., приводит при вызове к ошибке компиляции «Ambiguous method call».
Когда типом варарга используется generic-параметр, возникает warning «Possible heap pollution from parameterized vararg type». Вам нужно убедиться, что вы понимаете в чем этот риск, что ваш код не приводит к heap pollution, и уведомить об этом компилятор аннотацией @SafeVarargs.
Для этого используется аргумент-массив. В нем может находиться любое количество элементов. Еще с Java 5 для этого случая добавился синтаксический сахар: Variable-length argument (vararg). Три точки ... ставятся между типом и именем переменной, и становится можно передать любое количество аргументов, не упаковывая их в массив.
На уровне байткода применение массива и варарга не отличаются: vararg-параметр Foo... превращается в параметр-массив Foo[], на этапе вызова подставляется неявное инстанцирование и заполнение массива.
Чтобы избежать неоднозначностей, на vararg наложено ограничение: им может быть только один последний аргумент.
Vararg, как массив, может быть пустым. Иногда это приводит к неочевидному поведению. Допустим, имеем две перегрузки метода с аргументами int... и float.... Вызов такого метода без параметров попадает в вариант с int, как с более специфичным типом. Наличие же перегрузки с несовместимыми типами, например int... и boolean..., приводит при вызове к ошибке компиляции «Ambiguous method call».
Когда типом варарга используется generic-параметр, возникает warning «Possible heap pollution from parameterized vararg type». Вам нужно убедиться, что вы понимаете в чем этот риск, что ваш код не приводит к heap pollution, и уведомить об этом компилятор аннотацией @SafeVarargs.
👍9🔥2
Что если блок finally выбросит исключение?
Блок finally выполняется вне зависимости от того, было ли выброшено в его блоке try исключение, или нет. Когда исключение не случилось в try, но случилось в finally, нет ничего интересного. Это исключение как обычно пойдет вверх по стеку вызовов, пока не попадется в соответствующий ему catch.
Вопрос подразумевает второй случай, когда исполнение попадает в finally в момент выброса исключения из try. Исключение из finally заменит собой исключение из try и пойдет вверх по стеку вместо него. Оригинальная проблема будет попросту забыта.
Такая маскировка исключения усложняет отладку, лучше избегать её. Например IntelliJ IDEA выводит соответствующее предупреждение на оператор throw внутри finally.
Блок finally выполняется вне зависимости от того, было ли выброшено в его блоке try исключение, или нет. Когда исключение не случилось в try, но случилось в finally, нет ничего интересного. Это исключение как обычно пойдет вверх по стеку вызовов, пока не попадется в соответствующий ему catch.
Вопрос подразумевает второй случай, когда исполнение попадает в finally в момент выброса исключения из try. Исключение из finally заменит собой исключение из try и пойдет вверх по стеку вместо него. Оригинальная проблема будет попросту забыта.
Такая маскировка исключения усложняет отладку, лучше избегать её. Например IntelliJ IDEA выводит соответствующее предупреждение на оператор throw внутри finally.
👍21
Пройди тест по Java и проверь свои знания, готов ли ты к обучению на курсе.
Ответишь — пройдешь на продвинутый курс "Java Developer. Professional" от OTUS по специальной цене + получишь доступ к записям открытых уроков курса курса
Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5🔥2