Почему метод clone() объявлен в классе Object, а не в интерфейсе Cloneable?
Метод clone() объявлен в классе Object с указанием модификатора native, чтобы обеспечить доступ к стандартному механизму поверхностного копирования объектов. Одновременно он объявлен и как protected, чтобы нельзя было вызвать этот метод у не переопределивших его объектов. Непосредственно интерфейс Cloneable является маркерным (не содержит объявлений методов) и нужен только для обозначения самого факта, что данный объект готов к тому, чтобы быть клонированным. Вызов переопределённого метода clone() у не Cloneable объекта вызовет выбрасывание CloneNotSupportedException.
👉👆
Метод clone() объявлен в классе Object с указанием модификатора native, чтобы обеспечить доступ к стандартному механизму поверхностного копирования объектов. Одновременно он объявлен и как protected, чтобы нельзя было вызвать этот метод у не переопределивших его объектов. Непосредственно интерфейс Cloneable является маркерным (не содержит объявлений методов) и нужен только для обозначения самого факта, что данный объект готов к тому, чтобы быть клонированным. Вызов переопределённого метода clone() у не Cloneable объекта вызовет выбрасывание CloneNotSupportedException.
👉👆
Интервью с создателем Java Джеймсом Гослингом
Джеймс Гослинг, более известный как отец языка программирования Java, — специалист в области Computer Science из Канады. Он придумал изначальную архитектуру языка программирования Java, написал для него первый компилятор и виртуальную машину. Наш DevRel, Григорий Петров, взял интервью у Джеймса, и мы приводим полный текст этого интервью в русском переводе. Приятного чтения!
https://evrone.ru/james-gosling-interview
👉👆
Джеймс Гослинг, более известный как отец языка программирования Java, — специалист в области Computer Science из Канады. Он придумал изначальную архитектуру языка программирования Java, написал для него первый компилятор и виртуальную машину. Наш DevRel, Григорий Петров, взял интервью у Джеймса, и мы приводим полный текст этого интервью в русском переводе. Приятного чтения!
https://evrone.ru/james-gosling-interview
👉👆
evrone.ru
Интервью создателя Java Джеймса Гослинга для Evrone
Джеймс Гослинг, более известный как отец языка программирования Java, — специалист в области Computer Science из Канады. Он придумал изначальную архитектуру языка программирования Java, написал для него первый компилятор и виртуальную машину. Наш DevRel,…
Что такое effectively final и что с ним делать
Начну с правильного ответа на вопрос выше. В точке Б мы получим предупреждение компилятора: local variables referenced from a lambda expression must be final or effectively final
В этом посте обсудим, что означает effectively final, о чём молчит спецификация и как менять переменные внутри лямбд.
Про модификатор final всё понятно — он запрещает изменение переменной
Чтобы компилятор не ругался, надо выполнить два условия:
1️⃣ Локальная переменная однозначно определена до начала лямбда-выражения
Так не скомпилируется:
JLS 15.27.2 говорит, что ограничение помогает избежать многопоточных проблем: The restriction to effectively final variables prohibits access to dynamically-changing local variables, whose capture would likely introduce concurrency problems
С первого взгляда звучит разумно. Основное применение лямбд — в рамках Stream API. В Stream API есть опция parallel(), которая запускает выполнение в разных потоках. Там и возникнут concurrency problems.
Но я не принимаю это объяснение, потому что:
🤔 С каких пор компилятор волнуют многопоточные проблемы? Вся многопоточка отдана под контроль разработчика с начала времён
🤔 Если локальная переменная станет полем класса, то компилятор перестанет ругаться. При этом вероятность concurrency problems увеличится в разы
Моя гипотеза: требование final/effectively final связано с особенностями реализации лямбд и ограничением модели памяти. Это технические сложности в JVM и ничего больше. Отсутствие многопоточных проблем, о которых говорится в JLS, это всего лишь следствие, а не причина.
❓ Как же менять переменные внутри лямбд?
1️⃣ Сделать переменную полем класса:
2️⃣ Использовать Atomic обёртку
Для примитивов:
Начну с правильного ответа на вопрос выше. В точке Б мы получим предупреждение компилятора: local variables referenced from a lambda expression must be final or effectively final
В этом посте обсудим, что означает effectively final, о чём молчит спецификация и как менять переменные внутри лямбд.
Про модификатор final всё понятно — он запрещает изменение переменной
final int count = 100;
count
всегда будет равен 100. Каждый, кто напишет count = 200;будет осуждён компилятором. Для ссылок схема такая же:
final User admin = User.createAdmin();Ссылка
admin
всегда будет указывать на объект User с параметрами админа. Никто не может её переприсвоить:❌ admin = new User(…)Effectively final называется переменная, значение которой не меняется после инициализации. По сути это тот же final, но без ключевого слова.
Чтобы компилятор не ругался, надо выполнить два условия:
1️⃣ Локальная переменная однозначно определена до начала лямбда-выражения
Так не скомпилируется:
int x;Вот так норм:
if (…) х = 10
int x;2️⃣ Переменная не меняется внутри лямбды и после неё
if (…) х = 10; else х = 15;
int х = 10;❓ Зачем нужно такое ограничение?
…лямбда…
❌ х = 15
User user = …
…лямбда…
❌ user = userRepository.findByName(…)
✅ user.setTIN(…)
JLS 15.27.2 говорит, что ограничение помогает избежать многопоточных проблем: The restriction to effectively final variables prohibits access to dynamically-changing local variables, whose capture would likely introduce concurrency problems
С первого взгляда звучит разумно. Основное применение лямбд — в рамках Stream API. В Stream API есть опция parallel(), которая запускает выполнение в разных потоках. Там и возникнут concurrency problems.
Но я не принимаю это объяснение, потому что:
🤔 С каких пор компилятор волнуют многопоточные проблемы? Вся многопоточка отдана под контроль разработчика с начала времён
🤔 Если локальная переменная станет полем класса, то компилятор перестанет ругаться. При этом вероятность concurrency problems увеличится в разы
Моя гипотеза: требование final/effectively final связано с особенностями реализации лямбд и ограничением модели памяти. Это технические сложности в JVM и ничего больше. Отсутствие многопоточных проблем, о которых говорится в JLS, это всего лишь следствие, а не причина.
❓ Как же менять переменные внутри лямбд?
1️⃣ Сделать переменную полем класса:
int count;Не лучший вариант, переменная доступна теперь другим потокам. Concurrency problems!
public void m() {
list.forEach(v -> count++);
}
2️⃣ Использовать Atomic обёртку
Для примитивов:
AtomicInteger count = new AtomicInteger(0);Для ссылок:
list.forEach(v -> count.incrementAndGet())
AtomicReference<User> user = new AtomicReference<>();3️⃣ Использовать массив с одним элементом
…map(i -> user.set(…))
int[] res = new int[] {0};Популярный вариант, который подходит и для примитивов, и для ссылок. Но мне больше нравится вариант с Atomic:)
list.forEach(v -> res[0]++);
Где и как вы можете использовать приватный конструктор?
Приватный (помеченный ключевым словом
👉👆
Приватный (помеченный ключевым словом
private
, скрытый) конструктор может использоваться публичным статическим методом генерации объектов данного класса. Также доступ к нему разрешён вложенным классам и может использоваться для их нужд.👉👆
Носить с собой цветок на удачу или сделать что-то конкретное, чтобы сохранить свои деньги в сложившихся обстоятельствах? ⤵️
Сейчас самый надежный актив — недвижка, тем более IT-ипотека стала доступной. Ставка от 3 до 5%.
Главное, правильно выбрать объект для покупки — квартиру можно будет сдавать в аренду и иметь пассивный доход из любой точки мира, или продать и заработать на росте стоимости.
Чекайте всё самое важное про IT-ипотеку:
— Новые упрощенные условия
— Быстрая проверка аккредитации вашей IT-компании
— Сравнение расчётов по IT-ипотеке с другими программами
И сразу смотрите ТОП 4 квартиры, которые для вас уже подобрали и рассчитали по самым выгодным условиям.
Подписывайтесь на канал Анны Жуковой, где она публикует лучшие предложения по недвижке для айтишников и не только — https://t.me/anna_zuki
Деньги будут работать на вас и приносить новые деньги, а вы спокойно будете жить там, где вам комфортно )
Сейчас самый надежный актив — недвижка, тем более IT-ипотека стала доступной. Ставка от 3 до 5%.
Главное, правильно выбрать объект для покупки — квартиру можно будет сдавать в аренду и иметь пассивный доход из любой точки мира, или продать и заработать на росте стоимости.
Чекайте всё самое важное про IT-ипотеку:
— Новые упрощенные условия
— Быстрая проверка аккредитации вашей IT-компании
— Сравнение расчётов по IT-ипотеке с другими программами
И сразу смотрите ТОП 4 квартиры, которые для вас уже подобрали и рассчитали по самым выгодным условиям.
Подписывайтесь на канал Анны Жуковой, где она публикует лучшие предложения по недвижке для айтишников и не только — https://t.me/anna_zuki
Деньги будут работать на вас и приносить новые деньги, а вы спокойно будете жить там, где вам комфортно )
В чем заключается особенность работы метода clone () с полями объекта типа ссылки?
При клонировании объектов копируются только примитивные значения и значение ссылок на объекты. Это значит, что если объект имеет во внутреннем поле ссылку на другой объект, то будет клонирована только эта ссылка, сам же этот другой объект клонирован не будет. Собственно, это и называют — поверхностным клонированием.
Ну а что, если вам нужно полноценное клонирование с клонированием всех вложенных объектов? Как сделать, чтобы это были не копии ссылок, а полноценные клоны объекты с другими занимаемыми ячейками памяти в куче?
На самом деле все довольно просто — для этого вам нужно в каждом классе этих внутренних объектов также переопределить метод clone() и добавить интерфейс маркер — Cloneable. Тогда будут скопированные не ссылки на объекты, а сами объекты, ведь теперь они тоже имеют возможность копировать себя.
#вопросы_с_собеседований
Ну а что, если вам нужно полноценное клонирование с клонированием всех вложенных объектов? Как сделать, чтобы это были не копии ссылок, а полноценные клоны объекты с другими занимаемыми ячейками памяти в куче?
На самом деле все довольно просто — для этого вам нужно в каждом классе этих внутренних объектов также переопределить метод clone() и добавить интерфейс маркер — Cloneable. Тогда будут скопированные не ссылки на объекты, а сами объекты, ведь теперь они тоже имеют возможность копировать себя.
Не верьте ChatGPT и используйте KotUniL
В последние недели медиа и социальные сети захлеснул поток сообщений о диалогах с ChatGPT. Только на Хабре поиск по этому термину показывает сегодня полтора десятка статей.
Попробовал пообщаться с ChatGPT и я. Результат общения вынесен в заголовок.
Хотите узнать, почему ChatGPT верить нельзя и почему лучше использовать KotUniL - читайте дальше.
А если вы решили читать дальше, не воспринимайте заголовок буквально. Это все-таки ирония. К сожалению, я не предупредил об этом читателей в первом варианте этой статьи и получил в результате массу минусов.
Итак, как было дело.
Сначала я пообщался с ChatGPT (далее для простоты я буду иногда обозначать его ИИ) на английском, а потом на русском.
https://habr.com/ru/post/707548/
👉👆
В последние недели медиа и социальные сети захлеснул поток сообщений о диалогах с ChatGPT. Только на Хабре поиск по этому термину показывает сегодня полтора десятка статей.
Попробовал пообщаться с ChatGPT и я. Результат общения вынесен в заголовок.
Хотите узнать, почему ChatGPT верить нельзя и почему лучше использовать KotUniL - читайте дальше.
А если вы решили читать дальше, не воспринимайте заголовок буквально. Это все-таки ирония. К сожалению, я не предупредил об этом читателей в первом варианте этой статьи и получил в результате массу минусов.
Итак, как было дело.
Сначала я пообщался с ChatGPT (далее для простоты я буду иногда обозначать его ИИ) на английском, а потом на русском.
https://habr.com/ru/post/707548/
👉👆