Программист живёт нормально – Telegram
Программист живёт нормально
2.21K subscribers
140 photos
7 videos
29 files
79 links
Канал о программировании, программистах и жизни с программистами

Автор: @tkach1380
Download Telegram
Всем привет 🤖
Меня зовут Даниил и я Java-разработчик!
Я давно занимаюсь обучением и всегда хотел создать какое-то место, где я бы смог делиться тем, что знаю сам с большим, очень большим количеством людей😺

Вот и я тут!
🌭6👍1
Программист живёт нормально pinned «Всем привет 🤖 Меня зовут Даниил и я Java-разработчик! Я давно занимаюсь обучением и всегда хотел создать какое-то место, где я бы смог делиться тем, что знаю сам с большим, очень большим количеством людей😺 Вот и я тут!»
Итак, начнем с довольно остросоциальной темы☠️

#java #junior
Как передаются параметры в Java? По ссылке или по значению?

Очень часто люди отвечают как-то так: "Java передает примитивные типы по значению, а объекты по ссылке"
На самом деле ответ проще: Java всегда передает параметры по значению

Давайте разберемся в определениях:

Передача по значению (by value): Берется переменная, значение которой мы хотим использовать в методе. Значение этой переменной КОПИРУЕТСЯ и передается в метод.
Передача по ссылке (by reference): Берется переменная, значение которой мы хотим использовать в методе. Значение этой переменной НЕ КОПИРУЕТСЯ. В метод передается лишь УКАЗАТЕЛЬ на саму эту переменную (не на ОБЪЕКТ, а на ПЕРЕМЕННУЮ, которая указывает на ОБЪЕКТ)

С примитивными типами все понятно, в Java мы копируем значение переменных и считаем что-то в методе, самая настоящая передача по значению 👍

С ссылочными типами и возникают трудности. Часто под "передачей параметра по ссылке" люди имеют ввиду "передачу ссылки на объект".
Действительно, в Java в метод передается КОПИЯ ссылки на объект. Однако суть "передачи значения по ссылке" в том, что в метод передается НЕ ссылка на объект, а ссылка на переменную, которая уже ссылается на этот объект.

То есть при "передаче по ссылке" в методе мы получаем УКАЗАТЕЛЬ на ПЕРЕМЕННУЮ, которая в свою очередь указывает на ОБЪЕКТ.
А при "передаче по значению" в метод просто КОПИРУЕТСЯ ссылка на объект, и именно так и происходит в Java.

Java всегда передает параметры по значению 👩‍🎓
🔥31👍1
Многие знают, что объекты хранятся в области памяти Java, которая называется heap (куча), а примитивные типы данных хранятся в stack (стэке). А где же хранятся примитивные поля объектов? (пример ниже)
Anonymous Quiz
37%
В стэке
28%
В куче
35%
В виртуальной памяти
#java #junior
Где хранятся примитивные поля объектов? 🧳

Ответ односложен - в куче. Но почему же так происходит? Почему примитивные поля не могут храниться в стеке? 💆‍♀️

Для этого давайте откатимся назад и обсудим, что же такое стек?

Стековая память в Java работает по схеме LIFO (Последний зашел-Первый вышел)

Каждый раз, когда мы вызываем метод, в стеке формируется новый блок, который содержит все примитивы и ссылки на объекты (НЕ САМИ ОБЪЕКТЫ, они хранятся в куче)🧶

Как только метод завершается - этот блок УДАЛЯЕТСЯ из стека. Соответственно, все примитивы и ссылки на объекты удаляются из стека в этот же момент. Они больше нам не нужны, потому что все расчёты с ними мы завершили (как вы знаете, область доступности переменной в Java ограничивается блоком = фигурными скобками, в которых она объявлена)

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

Именно для сохранения целостности объекта все поля этого объекта сохраняются в КУЧЕ, и никак иначе🕶
👍4
#java #middle
Почему не всегда использование всех фишек подключаемых библиотек – это хорошо? 🌪

Зачастую, подключая какую-либо библиотеку к проекту, мы верим ей почти беспрекословно. Кажется, что всё, что мы подключаем к проекту, изначально не может содержать ошибок или недоработок.

Но это не так! Зачастую в библиотеках есть большое количество и неисправленных багов, и экспериментальных фишек ⚠️

Такая ситуация случилась со мной совсем недавно: я использовал библиотеку для автогенерации кода Lombok, которая позволяет не создавать конструкторы, сеттеры, геттеры самостоятельно, а генерирует их за счет добавления аннотаций. Например, при добавлении @Getter над классом, эта библиотека создаст геттеры для всех полей этого класса. Очень удобно.

И вот я разрабатываю класс-утилиту – вспомогательный класс, все члены которого статические, а экземпляры этого класса не могут существовать (создается приватный конструктор). Примером такого класса является java.lang.Math.

В этот момент мне приходит идея использовать аннотацию @UtilityClass, которая как раз создает, и приватный конструктор и запрещает создание любых других конструктор. И более того, помечает класс final. Жизнь сладка! 🍏

Ан нет! Я не прочитал документацию на эту аннотацию (а стоило): https://projectlombok.org/features/experimental/UtilityClass

В какой-то момент сборка проекта начала падать, и я обнаружил, что причин для этого нет: IDE не подсвечивает ничего красным, да и сам проект выглядит рабочим. Почти час времени я потратил на то, чтобы выяснить, что если эта аннотация используется, то статический импорт из этого класса возможен только с использованием звездочки, а не с указанием конкретного метода.

То есть (на примере java.lang.Math) так бы сработало: import static java.lang.Math.*
А так нет: import static java.lang.Math.PI

Открыв документацию, мы сразу видим надпись «Experimental» и описание той самой проблемы, о которой я писал выше.
Используя библиотеки – будьте внимательны к экспериментальным фишкам! ♨️
🤔4
Пример работы аннотации
👍1
А это описание аннотации. Также перевел на русский для общего понимания темы для тех, кто плохо понимает английский
👍2