Java библиотека
31.6K subscribers
2.15K photos
62 videos
6 files
1.84K links
Книги, статьи, мемы и многое другое для Java программиста!

По сотрудничеству и рекламе: @NadikaKir

Канал в перечне РКН: https://vk.cc/cJrT4A

Мы на бирже: https://telega.in/c/javalib/

Сообщество VK https://vk.com/javatutorial
Download Telegram
Расскажите про приведение типов. Что такое понижение и повышение типа?

Java является строго типизированным языком программирования, а это означает, то что каждое выражение и каждая переменная имеет строго определенный тип уже на момент компиляции. Однако определен механизм приведения типов (casting) - способ преобразования значения переменной одного типа в значение другого типа.

В Java существуют несколько разновидностей приведения:

Тождественное (identity). Преобразование выражения любого типа к точно такому же типу всегда допустимо и происходит автоматически.
Расширение (повышение, upcasting) примитивного типа (widening primitive). Означает, что осуществляется переход от менее емкого типа к более ёмкому. Например, от типа byte (длина 1 байт) к типу int (длина 4 байта). Такие преобразование безопасны в том смысле, что новый тип всегда гарантировано вмещает в себя все данные, которые хранились в старом типе и таким образом не происходит потери данных. Этот тип приведения всегда допустим и происходит автоматически.
Сужение (понижение, downcasting) примитивного типа (narrowing primitive). Означает, что переход осуществляется от более емкого типа к менее емкому. При таком преобразовании есть риск потерять данные. Например, если число типа int было больше 127, то при приведении его к byte значения битов старше восьмого будут потеряны. В Java такое преобразование должно совершаться явным образом, при этом все старшие биты, не умещающиеся в новом типе, просто отбрасываются - никакого округления или других действий для получения более корректного результата не производится.
Расширение объектного типа (widening reference). Означает неявное восходящее приведение типов или переход от более конкретного типа к менее конкретному, т.е. переход от потомка к предку. Разрешено всегда и происходит автоматически.
Сужение объектного типа (narrowing reference). Означает нисходящее приведение, то есть приведение от предка к потомку (подтипу). Возможно только если исходная переменная является подтипом приводимого типа. При несоответствии типов в момент выполнения выбрасывается исключение ClassCastException. Требует явного указания типа.
Преобразование к строке (to String). Любой тип может быть приведен к строке, т.е. к экземпляру класса String.
Запрещенные преобразования (forbidden). Не все приведения между произвольными типами допустимы. Например, к запрещенным преобразованиям относятся приведения от любого ссылочного типа к примитивному и наоборот (кроме преобразования к строке). Кроме того, невозможно привести друг к другу классы, находящиеся на разных ветвях дерева наследования и т.п.

При приведении ссылочных типов с самим объектом ничего не происходит, - меняется лишь тип ссылки, через которую происходит обращение к объекту.

Для проверки возможности приведения нужно воспользоваться оператором instanceof:

Parent parent = new Child();
if (parent instanceof Child) {
Child child = (Child) parent;
}
Несмотря на то, что Java 11 была выпущена в сентябре 2018 года, а Java 17 — в 2021 году, даже сегодня многие разработчики по-прежнему используют Java 11 или даже Java 8. 🙈

В предложенном докладе, Nikhil Nanivadekar постарается убедить вас перейти с Java 8 или с Java 11 на Java 17 и на реальных примерах продемонстрирует:
✔️ Новые фичи
✔️ Улучшения функционала
✔️ Сравнение производительности различных версий Java
и др.

Приятного просмотра!
Друзья, пришла зима, а значит, время поделиться планами на этот морозный декабрь!

🔷 9 декабря в Санкт-Петербурге стартует конференция «Технологии ПСБ. Поговорим в СПб»


📋 О чем будем говорить?

За один день с экспертами разных ИТ-направлений ПСБ участники узнают о том, как создавать, развивать и эффективно управлять цифровыми сервисами для крупного банка. И как делать это без потери качества и связи с клиентами!

📍 Сайт мероприятия — скорее регистрируйтесь!

▪️ Микросервисы

▪️ DevOps

▪️ Shift-left testing и развитие команды

🔷 Всё это и многое другое в докладах наших спикеров!

Регистрируйтесь сами и поделитесь приглашением со знакомыми из ИТ, которым интересны эти темы!

ID рекламы:

Pb3XmBtztBQYqCwkpwUudGm7n4r9SEEd67mqd1Q
Почему String неизменяемый и финализированный класс?

Есть несколько преимуществ в неизменности строк:

• Пул строк возможен только потому, что строка неизменяемая, таким образом виртуальная машина сохраняет больше свободного места в Heap, поскольку разные строковые переменные указывают на одну и ту же переменную в пуле. Если бы строка была изменяемой, то интернирование строк не было бы возможным, потому что изменение значения одной переменной отразилось бы также и на остальных переменных, ссылающихся на эту строку.
• Если строка будет изменяемой, тогда это станет серьезной угрозой безопасности приложения. Например, имя пользователя базы данных и пароль передаются строкой для получения соединения с базой данных и в программировании сокетов реквизиты хоста и порта передаются строкой. Так как строка неизменяемая, её значение не может быть изменено, в противном случае злоумышленник может изменить значение ссылки и вызвать проблемы в безопасности приложения.
• Неизменяемость позволяет избежать синхронизации: строки безопасны для многопоточности и один экземпляр строки может быть совместно использован различными потоками.
• Строки используются classloader и неизменность обеспечивает правильность загрузки класса.
• Поскольку строка неизменяемая, её hashCode() кэшируется в момент создания и нет необходимости рассчитывать его снова. Это делает строку отличным кандидатом для ключа в HashMap т.к. его обработка происходит быстрее.
Вашему вниманию предлагается новая подборка Java-новостей от InfoQ: 😃
✔️ Стал доступен билд № 26 для JDK 20 (ранний доступ)
✔️ Вышел релиз Spring Integration 6.0
✔️ AWS выкатил новую фичу для AWS Lambda - Lambda SnapSTart
✔️ Вышел релиз Apache Camel 3.18.4
и д.р.

Приятного чтения!

Читать статью
Почему char[] предпочтительнее String для хранения пароля?

С момента создания строка остаётся в пуле, до тех пор, пока не будет удалена сборщиком мусора. Поэтому, даже после окончания использования пароля, он некоторое время продолжает оставаться доступным в памяти и способа избежать этого не существует. Это представляет определённый риск для безопасности, поскольку кто-либо, имеющий доступ к памяти сможет найти пароль в виде текста. В случае использования массива символов для хранения пароля имеется возможность очистить его сразу по окончанию работы с паролем, позволяя избежать риска безопасности, свойственного строке.
Шпаргалка: исключения в Java

Друзья, представляем вашему вниманию шпаргалку на тему исключений в Java. 🤓

Хорошей памяти!

Читать статью
Почему строка является популярным ключом в HashMap в Java?

Поскольку строки неизменяемы, их хэш код вычисляется и кэшируется в момент создания, не требуя повторного пересчета при дальнейшем использовании. Поэтому в качестве ключа HashMap они будут обрабатываться быстрее.
Что делает метод intern() в классе String?

Метод intern() используется для сохранения строки в пуле строк или получения ссылки, если такая строка уже находится в пуле.
ТОП 30+ вопросов по ООП с примерами

Друзья, давно не освежали в памяти базовые понятия ООП. 😃

В предложенной сегодня статье представлены ТОП 30 вопросов по ООП с примерами.

Хорошей подготовки!

Читать статью
Можно ли использовать строки в конструкции switch?

Да, начиная с Java 7 в операторе switch можно использовать строки, ранние версии Java не поддерживают этого. При этом:
• участвующие строки чувствительны к регистру;
• используется метод equals() для сравнения полученного значения со значениями case, поэтому во избежание NullPointerException стоит предусмотреть проверку на null.
• согласно документации, Java 7 для строк в switch, компилятор Java формирует более эффективный байткод для строк в конструкции switch, чем для сцепленных условий if-else.
Двадцать бабушек – уже рубль. Как GraalVM Native Image позволяет экономить джавистам и девопсам деньги на облако

Мы поговорим об экономии на облаках в мире победившего Кубернетиса, обсудим перформанс современного приложения, и какие ништяки Native Image помогут нам во всём этом.

Mad skills bonus: вы сможете писать на Java приложения для командной строки так, что они не будут тормозить по сравнению со скриптами на Bash. Но вначале небольшая телега вместо вступления.

Читать статью
Какая основная разница между String, StringBuffer, StringBuilder?

Класс String является неизменяемым (immutable) - модифицировать объект такого класса нельзя, можно лишь заменить его созданием нового экземпляра.

Класс StringBuffer изменяемый - использовать StringBuffer следует тогда, когда необходимо часто модифицировать содержимое.

Класс StringBuilder был добавлен в Java 5 и он во всем идентичен классу StringBuffer за исключением того, что он не синхронизирован и поэтому его методы выполняются значительно быстрей.
Запросы к MongoDB из Java с помощью билдера фильтров

В этой статье разберемся, как использовать класс Filters для запросов к MongoDB.

Класс Filters представляет собой билдер для удобного написания фильтров запросов. Фильтры — это некоторые условные операции, которые MongoDB использует для ограничения результатов.

Читать статью
Что такое класс Object? Какие в нем есть методы?

Object это базовый класс для всех остальных объектов в Java. Любой класс наследуется от Object и, соответственно, наследуют его методы:

public boolean equals(Object obj) – служит для сравнения объектов по значению;

int hashCode() – возвращает hash код для объекта;

String toString() – возвращает строковое представление объекта;

Class getClass() – возвращает класс объекта во время выполнения;

protected Object clone() – создает и возвращает копию объекта;

void notify() – возобновляет поток, ожидающий монитор;

void notifyAll() – возобновляет все потоки, ожидающие монитор;

void wait() – остановка вызвавшего метод потока до момента пока другой поток не вызовет метод notify() или notifyAll() для этого объекта;

void wait(long timeout) – остановка вызвавшего метод потока на определённое время или пока другой поток не вызовет метод notify() или notifyAll() для этого объекта;

void wait(long timeout, int nanos) – остановка вызвавшего метод потока на определённое время или пока другой поток не вызовет метод notify() или notifyAll() для этого объекта;

protected void finalize() – может вызываться сборщиком мусора в момент удаления объекта при сборке мусора.
Пишем Java код используя проект Lombok

Можно долго спорить о необходимости и полезности проекта Lombok, но факт есть факт: количество кода для написания программы значительно сокращается. 😳

Предложенная сегодня статья расскажет о следующем:
✔️ Как работает Lombok
✔️ Формирование методов класса Object
✔️ Настройка аннотаций
✔️ Иммутабельные структуры данных
✔️ Delombok
и др.

Приятного чтения!

Читать статью
Расскажите про клонирование объектов.

Использование оператора присваивания не создает нового объекта, а лишь копирует ссылку на объект. Таким образом, две ссылки указывают на одну и ту же область памяти, на один и тот же объект. Для создания нового объекта с таким же состоянием используется клонирование объекта.

Класс Object содержит protected метод clone(), осуществляющий побитовое копирование объекта производного класса. Однако сначала необходимо переопределить метод clone() как public для обеспечения возможности его вызова. В переопределенном методе следует вызвать базовую версию метода super.clone(), которая и выполняет собственно клонирование.

Чтобы окончательно сделать объект клонируемым, класс должен реализовать интерфейс Cloneable. Интерфейс Cloneable не содержит методов относится к маркерным интерфейсам, а его реализация гарантирует, что метод clone() класса Object возвратит точную копию вызвавшего его объекта с воспроизведением значений всех его полей. В противном случае метод генерирует исключение CloneNotSupportedException. Следует отметить, что при использовании этого механизма объект создается без вызова конструктора.

Это решение эффективно только в случае, если поля клонируемого объекта представляют собой значения базовых типов и их обёрток или неизменяемых (immutable) объектных типов. Если же поле клонируемого типа является изменяемым ссылочным типом, то для корректного клонирования требуется другой подход. Причина заключается в том, что при создании копии поля оригинал и копия представляют собой ссылку на один и тот же объект. В этой ситуации следует также клонировать и сам объект поля класса.

Такое клонирование возможно только в случае, если тип атрибута класса также реализует интерфейс Cloneable и переопределяет метод clone(). Так как, если это будет иначе вызов метода невозможен из-за его недоступности. Отсюда следует, что если класс имеет суперкласс, то для реализации механизма клонирования текущего класса-потомка необходимо наличие корректной реализации такого механизма в суперклассе. При этом следует отказаться от использования объявлений final для полей объектных типов по причине невозможности изменения их значений при реализации клонирования.

Помимо встроенного механизма клонирования в Java для клонирования объекта можно использовать:

Специализированный конструктор копирования - в классе описывается конструктор, который принимает объект этого же класса и инициализирует поля создаваемого объекта значениями полей переданного.
Фабричный метод - (Factory method), который представляет собой статический метод, возвращающий экземпляр своего класса.
• Механизм сериализации - сохранение и последующее восстановление объекта в/из потока байтов.
Как ускорить прогон тестов в многомодульном проекте Maven

Большое количество модулей Maven замедляет сборку проекта и время прогона тестов. Для того, чтобы сохранить многомодульную структуру проекта и быстро прогонять тесты, мы в Wrike написали новый инструмент — Maven Modules Merger, который сократил время некоторых сборок с 50 до 12 минут. В статье подробно расскажу о том, с какими проблемами нам помог справиться Maven Modules Merger и поделюсь подробностями его создания.

Читать статью
В чем отличие между поверхностным и глубоким клонированием?

Поверхностное копирование копирует настолько малую часть информации об объекте, насколько это возможно. По умолчанию, клонирование в Java является поверхностным, т.е. класс Object не знает о структуре класса, которого он копирует. Клонирование такого типа осуществляется JVM по следующим правилам:

• Если класс имеет только члены примитивных типов, то будет создана совершенно новая копия объекта и возвращена ссылка на этот объект.
• Если класс помимо членов примитивных типов содержит члены ссылочных типов, то тогда копируются ссылки на объекты этих классов. Следовательно, оба объекта будут иметь одинаковые ссылки.

Глубокое копирование дублирует абсолютно всю информацию объекта:
• Нет необходимости копировать отдельно примитивные данные;
• Все члены ссылочного типа в оригинальном классе должны поддерживать клонирование. Для каждого такого члена при переопределении метода clone() должен вызываться super.clone();
• Если какой-либо член класса не поддерживает клонирование, то в методе клонирования необходимо создать новый экземпляр этого класса и скопировать каждый его член со всеми атрибутами в новый объект класса, по одному.
RabbitMQ + Spring boot + Docker. Отправляем и получаем сообщения через Producer и Consumer. Пошаговое руководство

Меня зовут Андрей Вербицкий и я столкнулся с тем, что мое знакомство с RabbitMQ, а в частности его запуск на локальной машине и отправка сообщений в очередь с помощью приложения на Spring Boot, вылилась в несколько дней поисков информации о том, как это вообще работает, какие есть сущности и как в итоге переслать это сообщение. Я решил собрать все это в одном месте и сделать из этого практическое руководство, которое поможет из ничего получить рабочий прототип и понять как это работает. Эта статья ориентированная на новичков, которые только хотят познакомиться с RabbitMQ. Целью я поставил максимально простыми словами и по шагам рассказать, как быстро и легко поднять все окружение локально, отправить и получить сообщения через очередь.

Читать статью