Никогда не используйте Cloneable!
Тут Тагир Валеев написал в Твиттере, что clone() это неплохая штука, если ей правильно пользоваться. Я с этим категорически не согласен. clone() — ужаснейшая вещь. Попробую объяснить почему.
Давайте вспомним, что это вообще такое. Cloneable — наследие с самой первой версии Java. Это интерфейс, который позволяет легко добавлять возможность копирования объектов наших классов. Для этого мы просто наследуем класс от интерфейса Cloneable, и JVM с помощью некоторой магии генерирует нам реализацию метода clone(), которая будет делать копии путём простого копирования полей. При этом сам метод clone является protected методом в классе java.lang.Object, и поэтому доступен для каждого класса, в том числе для тех, кому клонирование нафиг не нужно (это 99% классов).
Здесь можно провести полную аналогию с сериализацией. Если в сериализации есть интерфейс Serializable, который не содержит методов и является интерфейсом-маркером, и при его реализации класс автоматически становится сериализуемым, то в этом случае есть интерфейс Cloneable, который тоже не содержит методов и также является интерфейсом-маркером, и при его реализации класс автоматически становится клонируемым.
Какие проблемы есть у такого механизма клонирования?
Во-первых, это отсутствие статических проверок. Можно забыть отнаследоваться от интерфейса Cloneable и спокойно при этом пользоваться методом clone(). Об ошибке мы узнаем только во время выполнения, когда вылетит CloneNotSupportedException.
Во-вторых, это необходимость downcasting’а при вызове метода clone(). Из-за того, что метод clone() в классе java.lang.Object возвращает Object, нам приходится делать явный cast, чтобы привести его к конкретному типу. Например, если вы вызовете ArrayList.clone(), то вам вернётся Object, а не ArrayList, и вам придётся скастовать к ArrayList. Во времена Java 1.0 это не казалось проблемой, поскольку тогда downcasting был совершенно привычной практикой, но сегодня большинство программистов старается избегать написания подобного нетипобезопасного кода.
В-третьих, так как в большинстве случаев, чтобы нести какую-то пользу, метод clone() должен быть публичным, то нам приходится переопределять метод clone() с одной лишь целью — изменить protected на public! При этом при переопределении метода clone() приходится писать абсолютно бесполезный код, в котором не делается ничего полезного кроме вызова super-метода и перебрасывания CloneNotSupportedException.
И это четвёртая проблема: CloneNotSupportedException является checked-исключением. Checked-исключения — это одна из вещей, от которой я бы тоже с удовольствием избавился в Java. От них вреда намного больше, чем пользы. Можно это как-нибудь позже более подробно обсудить. И если, в том, что, например, IOException является checked-исключением, есть хоть какой-то смысл, то в том, что CloneNotSupportedException сделали checked, смысла нет никакого. Заставлять каждый раз ловить CloneNotSupportedException при вызове clone() — чем думали создатели??
Какое есть решение у вышеперечисленных проблем? Решение простое — просто никогда не использовать Cloneable и метод clone(). Ну разве что за исключением клонирования массивов (это единственное исключение). В остальных случаях, если хочется иметь копирование, можно просто написать свой конструктор копирования или метод копирования, например назвав его copy(). Это будет намного лучше, прозрачнее и безопаснее, чем метод clone(), который создавал бы копию объекта на основе магии и в обход конструктора.
Тут Тагир Валеев написал в Твиттере, что clone() это неплохая штука, если ей правильно пользоваться. Я с этим категорически не согласен. clone() — ужаснейшая вещь. Попробую объяснить почему.
Давайте вспомним, что это вообще такое. Cloneable — наследие с самой первой версии Java. Это интерфейс, который позволяет легко добавлять возможность копирования объектов наших классов. Для этого мы просто наследуем класс от интерфейса Cloneable, и JVM с помощью некоторой магии генерирует нам реализацию метода clone(), которая будет делать копии путём простого копирования полей. При этом сам метод clone является protected методом в классе java.lang.Object, и поэтому доступен для каждого класса, в том числе для тех, кому клонирование нафиг не нужно (это 99% классов).
Здесь можно провести полную аналогию с сериализацией. Если в сериализации есть интерфейс Serializable, который не содержит методов и является интерфейсом-маркером, и при его реализации класс автоматически становится сериализуемым, то в этом случае есть интерфейс Cloneable, который тоже не содержит методов и также является интерфейсом-маркером, и при его реализации класс автоматически становится клонируемым.
Какие проблемы есть у такого механизма клонирования?
Во-первых, это отсутствие статических проверок. Можно забыть отнаследоваться от интерфейса Cloneable и спокойно при этом пользоваться методом clone(). Об ошибке мы узнаем только во время выполнения, когда вылетит CloneNotSupportedException.
Во-вторых, это необходимость downcasting’а при вызове метода clone(). Из-за того, что метод clone() в классе java.lang.Object возвращает Object, нам приходится делать явный cast, чтобы привести его к конкретному типу. Например, если вы вызовете ArrayList.clone(), то вам вернётся Object, а не ArrayList, и вам придётся скастовать к ArrayList. Во времена Java 1.0 это не казалось проблемой, поскольку тогда downcasting был совершенно привычной практикой, но сегодня большинство программистов старается избегать написания подобного нетипобезопасного кода.
В-третьих, так как в большинстве случаев, чтобы нести какую-то пользу, метод clone() должен быть публичным, то нам приходится переопределять метод clone() с одной лишь целью — изменить protected на public! При этом при переопределении метода clone() приходится писать абсолютно бесполезный код, в котором не делается ничего полезного кроме вызова super-метода и перебрасывания CloneNotSupportedException.
И это четвёртая проблема: CloneNotSupportedException является checked-исключением. Checked-исключения — это одна из вещей, от которой я бы тоже с удовольствием избавился в Java. От них вреда намного больше, чем пользы. Можно это как-нибудь позже более подробно обсудить. И если, в том, что, например, IOException является checked-исключением, есть хоть какой-то смысл, то в том, что CloneNotSupportedException сделали checked, смысла нет никакого. Заставлять каждый раз ловить CloneNotSupportedException при вызове clone() — чем думали создатели??
Какое есть решение у вышеперечисленных проблем? Решение простое — просто никогда не использовать Cloneable и метод clone(). Ну разве что за исключением клонирования массивов (это единственное исключение). В остальных случаях, если хочется иметь копирование, можно просто написать свой конструктор копирования или метод копирования, например назвав его copy(). Это будет намного лучше, прозрачнее и безопаснее, чем метод clone(), который создавал бы копию объекта на основе магии и в обход конструктора.
Twitter
Tagir Valeev
I used Cloneable and Object.clone() method in production code and happy about it. That was the best way to solve my problem.
Ребята, провожу небольшое исследование. Нужно ответить на один вопрос. Как вы работали до и как стали работать после вспышки коронавируса?
Final Results
80%
Работал в офисе, теперь удалённо
10%
Работал удалённо и продолжаю работать удалённо
4%
Работал в офисе и продолжаю работать в офисе
2%
Я стал безработным
5%
Другое
Forwarded from Ivan Ugliansky
Всем привет!
Мы закончили обработку видео и теперь публикуем их на нашем youtube-канале: https://www.youtube.com/playlist?list=PLecWId-JT7S6NvsX-8-_FSiwM2XsLoqH3
Простите за задержку с публикацией! Но надеемся, что теперь 13 видео отличных докладов скрасят вам остаток карантина и напомнят о нашем увлекательном последнем дне зимы :) Приятного просмотра!
Мы закончили обработку видео и теперь публикуем их на нашем youtube-канале: https://www.youtube.com/playlist?list=PLecWId-JT7S6NvsX-8-_FSiwM2XsLoqH3
Простите за задержку с публикацией! Но надеемся, что теперь 13 видео отличных докладов скрасят вам остаток карантина и напомнят о нашем увлекательном последнем дне зимы :) Приятного просмотра!
Forwarded from JUGNsk News
Друзья, уже совсем скоро, в 19-00 начнется наш первый онлайн митап с Алексеем Шипилёвым!
Вы уже можете заходить в Zoom конференцию, указанную на странице мероприятия на meetup.com (если зарегистрировались), либо начинать смотреть трансляцию на нашем youtube канале: https://www.youtube.com/watch?v=c1jVn5Sm8Uw
—
Заранее напишу несколько слов про то, как все будет организовано:
1. Алексей выступит с большим докладом из двух частей. Между ними и в самом конце будет время для вопросов и ответов. Вопрос можно задать: 1) в Zoom лично, 2) в нашем чате в телеграме, 3) в чате трансляции на youtube.
2. По умолчанию у участников будут отключены микрофоны, чтобы избежать случайного шума. Если вы хотите задать вопрос, пожалуйста, воспользуйтесь функцией "Поднять руку". Для этого в Zoom на вкладке "Manage Participants"/"Участники" выберите действие "Raise a hand"/"Поднять руку". После этого мы размьютим ваш микрофон.
3. Пожалуйста, включайте камеры! Хоть у нас и онлайн митап, но мы хотим по максимуму воспроизвести атмосферу нашего обычного офлайн митапа. И самое главное: так вы сделаете выступление более комфортным для спикера (кому понравится 2 часа говорить в пустоту?)
4. После основной части будет афтепати :) Все желающие смогут остаться и продолжить общение в свободной форме.
На этом все, ждем вас в 19-00!
Вы уже можете заходить в Zoom конференцию, указанную на странице мероприятия на meetup.com (если зарегистрировались), либо начинать смотреть трансляцию на нашем youtube канале: https://www.youtube.com/watch?v=c1jVn5Sm8Uw
—
Заранее напишу несколько слов про то, как все будет организовано:
1. Алексей выступит с большим докладом из двух частей. Между ними и в самом конце будет время для вопросов и ответов. Вопрос можно задать: 1) в Zoom лично, 2) в нашем чате в телеграме, 3) в чате трансляции на youtube.
2. По умолчанию у участников будут отключены микрофоны, чтобы избежать случайного шума. Если вы хотите задать вопрос, пожалуйста, воспользуйтесь функцией "Поднять руку". Для этого в Zoom на вкладке "Manage Participants"/"Участники" выберите действие "Raise a hand"/"Поднять руку". После этого мы размьютим ваш микрофон.
3. Пожалуйста, включайте камеры! Хоть у нас и онлайн митап, но мы хотим по максимуму воспроизвести атмосферу нашего обычного офлайн митапа. И самое главное: так вы сделаете выступление более комфортным для спикера (кому понравится 2 часа говорить в пустоту?)
4. После основной части будет афтепати :) Все желающие смогут остаться и продолжить общение в свободной форме.
На этом все, ждем вас в 19-00!
YouTube
Алексей Шипилёв – Shenandoah GC 2.0 (часть 1)
Первый online митап JUGNsk!
Выступает Алексей Шипилёв.
Тема доклада: "Shenandoah GC 2.0".
Одна из главных проблем больших Java-приложений — это cбо... рка мусо... ра. Хранение больших куч данных, активно фрагментирующие приложения и прочие выпадающие из…
Выступает Алексей Шипилёв.
Тема доклада: "Shenandoah GC 2.0".
Одна из главных проблем больших Java-приложений — это cбо... рка мусо... ра. Хранение больших куч данных, активно фрагментирующие приложения и прочие выпадающие из…
Марк Рейнолд объявил о новом проекте OpenJDK под кодовым названием Leyden. Цель проекта - уметь создавать из Java-программ самодостаточный статический образ с помощью AOT-компиляции. Похожая технология уже есть в GraalVM под названием Native Image, но она не будет использоваться при разработке.
К сожалению, паттерны деконструкции для записей не появятся в Java 15. Об этом было написано в рассылке, а соответствующая секция была убрана из JEP'а.
Как сказал Gavin Bierman, там есть некоторые сложности с дженериками и varargs, и нужно ещё время, чтобы подумать над дизайном.
Это значит, что в Java 15 изменений в паттерн-матчинге не будет.
Как сказал Gavin Bierman, там есть некоторые сложности с дженериками и varargs, и нужно ещё время, чтобы подумать над дизайном.
Это значит, что в Java 15 изменений в паттерн-матчинге не будет.
Telegram
miniJUG
В Java появятся паттерны деконструкции
В недавно вышедшем JEP 375 появилась информация о введении в язык так называемых паттернов деконструкции. Такие паттерны позволят применять оператор instanceof не просто для теста по типу, но и для извлечения компонентов…
В недавно вышедшем JEP 375 появилась информация о введении в язык так называемых паттернов деконструкции. Такие паттерны позволят применять оператор instanceof не просто для теста по типу, но и для извлечения компонентов…
Решил составить список русскоязычных Telegram-каналов про Java. Добавил туда те каналы, про которые знаю сам. Но наверняка есть ещё. Если вы знаете, то напишите в комментариях, чтобы я добавил.
P.S. Про чаты писать не нужно, только каналы.
P.S. Про чаты писать не нужно, только каналы.
Gist
Список русскоязычных Telegram-каналов про Java
Список русскоязычных Telegram-каналов про Java. GitHub Gist: instantly share code, notes, and snippets.
Скинули мне тут пару Telegram-каналов для добавления в список. Спасибо за это. Но я посмотрел на один из них и ужаснулся. Вот такой тест там. Я, будучи абсолютно уверенным, что правильный вариант четвёртый, проголосовал за него. Но правильным ответом по мнению автора должен быть второй. А теперь открываем javadoc к HashMap и читаем:
This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.
Порядок элементов в HashMap не гарантирован. Точка.
Да, де факто там выделяется массив такой длины, что числа 10, 20 и 30 выстроятся по порядку. Но это деталь реализации. Сегодня она такая, завтра другая. И эта деталь скрыта от нас, чтобы всегда была возможность оптимизировать, не ломая обратную совместимость. А если кто завяжется на порядок, то он рискует, что у него это сломается в какой-нибудь Java 18 или Java 88.
This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.
Порядок элементов в HashMap не гарантирован. Точка.
Да, де факто там выделяется массив такой длины, что числа 10, 20 и 30 выстроятся по порядку. Но это деталь реализации. Сегодня она такая, завтра другая. И эта деталь скрыта от нас, чтобы всегда была возможность оптимизировать, не ломая обратную совместимость. А если кто завяжется на порядок, то он рискует, что у него это сломается в какой-нибудь Java 18 или Java 88.
А ведь это Телеграм-канал с 3k подписчиков! Они прочитают это, и кто-то начнёт вызывать new HashMap с initialCapacity, чтобы гарантировать порядок вставки! А те кто поумнее, даже не смогут возразить, потому что это канал и он работает в одну сторону. Как телевизор. Напоминает Первый Канал, который в прайм-тайме на полном серьёзе рассказывает про то, что Билл Гейтс создал коронавирус, чтобы заработать на вакцине.
Кстати, это касается и моего канала. Если вы видите, что я написал откровенный бред, то обязательно напишите мне и укажите на ошибку! Написать мне можно в Твиттере.
Кстати, это касается и моего канала. Если вы видите, что я написал откровенный бред, то обязательно напишите мне и укажите на ошибку! Написать мне можно в Твиттере.
Рон Пресслер (лидер проекта Loom) выложил документ State of Loom. Есть что почитать на выходных.
#loom
#loom
Тут появилась новость о планах на C# 9.0. В нём появятся записи! Выглядеть будет примерно так:
Конечно прикольно, что нововведений много. Но не кажется ли вам, что в C# с каждым релизом становится всё больше и больше избыточного синтаксического сахара? У меня от C# примерно такие же ощущения, как от Котлина. В обоих языках просто перебор сахара. Как будто сожрал целую банку мёда.
public data class Person(string FirstName, string LastName);И ещё много интересного. Например, target types:
Point p = new (3, 5);
Top-level programs:using System;Covariant returns:
Console.WriteLine("Hello World!");
abstract class AnimalУдивительно, что эту фичу добавляют так поздно. В Java она присутствует с 1.5!
{
public abstract Food GetFood();
}
class Tiger : Animal
{
public override Meat GetFood() => ...;
}
Конечно прикольно, что нововведений много. Но не кажется ли вам, что в C# с каждым релизом становится всё больше и больше избыточного синтаксического сахара? У меня от C# примерно такие же ощущения, как от Котлина. В обоих языках просто перебор сахара. Как будто сожрал целую банку мёда.
Microsoft News
Welcome to C# 9.0
Note: This post is out of date. Now that C# 9.0 has been released, an updated version can be found here. C# 9.0 is taking shape, and I’d like to share our thinking on some of the major features we’re adding to this next version of the language. With every…
Ушёл писать Notepad драйвер для slf4j... https://twitter.com/nikitonsky/status/1265268383777460224
#юмор
#юмор
Twitter
Niki Tonsky
https://t.co/nRmQjwhEPW
В 12:00 по МСК сегодня будет беседа в прямом эфире с Тагиром Валеевым. Он кстати недавно стал Java-чемпионом. Тагир расскажет про свой доклад для JPoint 2020 и обсудит киллер-фичи в IntelliJ IDEA и в новых версиях Java.
YouTube
Первая чашка кофе с JPoint / Тагир Валеев // 03.06.2020
Подробнее о Java-конференциях:
— весной — JPoint: https://jrg.su/gTrwHx
— осенью — Joker: https://jrg.su/h7yvG4
— —
Телеграм-чат для обсуждения: https://tlgg.ru/@jpointconf
Утреннее шоу «Первая чашка кофе с JPoint» — это встречи программного комитета конференции…
— весной — JPoint: https://jrg.su/gTrwHx
— осенью — Joker: https://jrg.su/h7yvG4
— —
Телеграм-чат для обсуждения: https://tlgg.ru/@jpointconf
Утреннее шоу «Первая чашка кофе с JPoint» — это встречи программного комитета конференции…
Недавно вышло неплохое интервью с Сергеем Куксенко. Рекомендую послушать. Мне, например, понравилось его объяснение того, почему убирают biased locking. Я знаю, что многие были в недоумении, когда узнали, что его отключают по умолчанию в Java 15. Но под этим есть вполне чёткие основания. И это не просто потому, что biased locking значительно усложняет код и его поддержку. Но и потому, что у некоторых очень популярных инструментов он вообще давным-давно отключен, потому что без него производительность становится выше! Например, в Кассандре.
YouTube
Головы Гидры / Сергей Куксенко // 01.06.2020
Hydra 2022 — June 2-3
Info and tickets: https://bit.ly/3ni5Hem
— . Телеграм-чат для обсуждения: https://tlgg.ru/@hydraconf
«Головы Гидры» — это разговорное шоу конференции по разработке многопоточных и распределенных систем Hydra, где участники программного…
Info and tickets: https://bit.ly/3ni5Hem
— . Телеграм-чат для обсуждения: https://tlgg.ru/@hydraconf
«Головы Гидры» — это разговорное шоу конференции по разработке многопоточных и распределенных систем Hydra, где участники программного…
Внезапно узнал, что Rhino (движок для JavaScript) не только не умер, но и активно развивается. Можно использовать в качестве замены Nashorn, который исчезнет в Java 15.
#javanoscript #rhino
#javanoscript #rhino
GitHub
GitHub - mozilla/rhino: Rhino is an open-source implementation of JavaScript written entirely in Java
Rhino is an open-source implementation of JavaScript written entirely in Java - mozilla/rhino