Что такое даймонд оператор java

Diamond Operator in Java

Что такое даймонд оператор java. Смотреть фото Что такое даймонд оператор java. Смотреть картинку Что такое даймонд оператор java. Картинка про Что такое даймонд оператор java. Фото Что такое даймонд оператор java

Sep 18, 2018 · 2 min read

Что такое даймонд оператор java. Смотреть фото Что такое даймонд оператор java. Смотреть картинку Что такое даймонд оператор java. Картинка про Что такое даймонд оператор java. Фото Что такое даймонд оператор java

Diamond operator aka diamond syntax was introduced in Java 7 as a new feature. Purpose of the diamond operator is to simplify the use of generics when creating an object.

It avoids unchecked warnings in a program as well as reducing generic verbosity by not requiring explicit duplicate specification of parameter types.

Raw Types prior to Java 5

Before Java 5, the collections API supports only raw types. There was no way for type arguments be parameterized when constructing a collection.

The above code runs just fine, but suppose you also have the following:

Now we run i n to trouble at run-time, because the list contains something that isn’t an instanceof String.

Presumably, if you want names to contain only String, you could perhaps still use a raw type and manually check every add yourself, and then manually cast to String every item from names.

Generics from Java 5

Generics were introduced — which allowed us to parameterize the type arguments for classes,

Raw types refer to using a generic type without specifying a type parameter. For example, List is a raw type, while List is a parameterized type.

When generics were introduced in JDK 1.5, raw types were retained only to maintain backwards compatibility with older versions of Java.

At this point, we have to specify the parameterized type in the constructor, which can be somewhat unreadable:

Even though the compiler still allows us to use raw types in the constructor,

it will prompt us with a warning message:

ArrayList is a raw type. References to generic type ArrayList should be parameterized

Diamond Operator from Java 7

With Java 7, the diamond operator makes this shorter and simpler. It also adds type inference and reduces the verbosity in the assignments — when using generics:

It becomes even more useful with more complex data types, such as a List of Map objects as follows:

Simply put, the diamond operator adds the type inference feature to the compiler and reduces the verbosity in the assignments introduced with generics.

Generics allow us to keep the safety of generics with almost the same effort as using the raw type.

Источник

Выведение типов Java-компилятором

1. Синтаксический сахар

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

Разработчики Java сделали все, чтобы устранить из Java всю возможную избыточность. Если в C++ что-то можно сделать десятью способами, в Java чаще всего это можно сделать только одним способом.

Но такая унификация не нравится ни Java-программистам, ни создателям Java. И иногда они упрощают жизнь обычным ребятам вроде нас с вами.

Длинный кодКомпактный код

Вместо длинного кода как слева вы можете писать более компактный код, как справа. А умный Java-компилятор на основе краткого кода сам сгенерирует его полную версию. Это и есть синтаксический сахар.

2. Выведение типа переменной – var

В Java 11 компилятор стал еще умнее и теперь может определить тип создаваемой переменной по типу значения, которое ей присваивают. Выглядит это в коде так:

Где имя — это имя новой переменной, значение — ее стартовое значение, а var — это ключевое слово, используемое для объявления переменной. Тип у переменной имя будет такой же, как у значения, которое ей присваивают.

Как этот код видим мыЧто видит компилятор

Компилятор сам определяет или, как еще говорят, выводит тип переменной на основе значения, которое ей присваивают.

Немало копий было сломлено в баталиях программистов на тему того, стоит ли добавлять такую возможность в язык или нет. Многие боялись, что использованием var начнут злоупотреблять, и читаемость кода сильно снизится.

Доля истины в этом есть, так что лучше всего использовать var там, где это повышает читабельность кода. Например, этих в двух случаях:

Случай 1: глядя на значение переменной сразу ясно, какой тип у переменной

КодПояснение
У переменной тип InputStream
У переменной тип String
КодПояснение
Тип переменной определить сложно
Тип переменной определить сложно

Случай 2: тип переменной не важен для понимания кода

Часто в коде могут быть ситуации, когда у переменной не вызываются никакие методы – переменная просто используется для временного хранения чего-либо. Использование var тут абсолютно не снижает понимание кода:

Золотая середина

Сейчас приведу три способа записи одного и того же кода. Использование var будет оптимальным вариантом.

КодПримечание
Слишком компактно
Идеально
Слишком подробно

Когда мы перешли от варианта в строке 1 к варианту в строке 2, мы за счет имени переменной ( headerInfo ) добавили коду немного читаемости. Теперь ясно, что метод возвращал не просто метаинформацию, а информацию о заголовке.

Источник

Дельфин, монета и бриллиантовый оператор.

Релиз Java 7 должен выйти 28 Июля.
В связи с этой знаменательно датой, я наконец-то решил посмотреть, что нас всех ждет. Поскольку в последнее время в основном занимаюсь Scala, то на новые языковые фичи в Java не обращал серьезного внимания (только на тусовках java-программистов, плюс поглядывал что пишут в разных блогах жависты).

Что такое даймонд оператор java. Смотреть фото Что такое даймонд оператор java. Смотреть картинку Что такое даймонд оператор java. Картинка про Что такое даймонд оператор java. Фото Что такое даймонд оператор java

Технических новшеств очень много. Среди них самое интересное место занимает так называемый «Проект Монета (Project Coin)».

Он содержит в себе небольшие (конечно с их точки зрения) изменения в языке:

— Strings in switch
— Binary integral literals and underscores in numeric literals
— Multi-catch and more precise rethrow
— Improved type inference for generic instance creation (diamond)
— try-with-resources statement
— Simplified varargs method invocation

В этом посте я наверно не смогу написать про все фичи, пока хотел обратить внимание на некоторые интересные на мой взгляд моменты.

Improved type inference for generic instance creation (diamond)

Это так называемый оператор diamond (бриллиант, алмаз). Думаю называется так, потому что чем-то похож на камень: <>.

В качестве примера часто приводят такой код:

// Java 7 List a = new ArrayList<>(); // до Java 7 List b= new ArrayList ();

Это конечно очень красиво, т.к. мы смогли уменьшить размер кода. Но возникает вопрос, чем это лучше, если раньше можно сделать еще проще? Вот так:

// в Java 7 List a = new ArrayList<>(); // до Java 7 List b = new ArrayList();

Понятно, что мы здесь используем сырой тип (raw types) и поэтому некоторым программистам по «морально-этическим» соображениям такой код не нравится.
Хотя один java-программист даже не поленился и сравнил полученный байт-код: jdk-7-diamond-operator.
Он показал на примере, что никакой разницы от использования бриллианта в компилируемом байт-коде нет, т.к. весь этот сахар при компиляции пропадает.

Мне кажется, что более реальная польза, может быть показана в следующем примере:

List a = new ArrayList<>(); // Такой прокатит, хотя и ошибочный, что плохо. List b = new ArrayList(a); // Такой уже отрубится компилятором, что хорошо. List c = new ArrayList<>(a);

Таким образом, наш бриллиантик автоматически выведет тип. Затем поймет, что у нас должен быть конструктор от списка чисел. Потом компилятор понимает, что нам вместо этого подают список строк и создаст ошибку компиляции.

try-with-resource

Появился новый интерфейс AutoCloseable. Причем не где-то там в io (как Closeable), а в самом java.lang!

Этот интерфейс был подсунут в иерархию над Closeable (Closeable extends AutoCloseable).
Таким образом, автоматически все потоки (_Stream) и читатели/писатели(Reader/Writer) становятся также AutoCloseable.
В AutoCloseable есть один метод void close() throws Exception.

Идея заключается в том, что если указать AutoCloseable переменные (в терминах Java 7 они называются ресурсы) в скобочках после try, то они всегда автоматически закроются при выходе из try блока.

В качестве примера как правило приводят обычно что-то вроде:

Источник

В чем смысл оператора diamond в Java 7?

оператор diamond в java 7 позволяет использовать следующий код:

однако в Java 5/6, я могу просто написать:

мое понимание стирания типа заключается в том, что они точно такие же. (В любом случае generic удаляется во время выполнения).

зачем вообще возиться с бриллиантом? Какие новые функции / тип безопасности это позволяет? Если он не дает никаких новых функций, почему они упоминают его как функцию? Насколько я это понимаю? концепция ошибочна?

7 ответов

дженерики существуют для обеспечения защиты времени компиляции от неправильных действий. В приведенном выше примере использование типа raw означает, что вы не получаете эту защиту и получите ошибку во время выполнения. Вот почему вы не должны использовать сырые типы.

Я думаю, что главное понять, что сырые типы (без <> ) нельзя рассматривать так же, как и универсальные типы. Когда вы объявляете необработанный тип, вы не получаете ни одного из преимущества и проверка типа дженериков. Вы также должны иметь в виду, что дженерики являются частью общего назначения языка Java. они не просто применяются к конструкторам no-arg Collection s!

ваше понимание слегка искажено. Алмазный оператор-хорошая функция, так как вам не нужно повторяться. Имеет смысл определить тип один раз, когда вы объявляете тип, но просто не имеет смысла определять его снова с правой стороны. Сухой принцип.

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

С помощью List list = new LinkedList() получите предупреждения rawtype.

эта строка вызывает предупреждение [unchecked]:

Итак, вопрос трансформируется: почему предупреждение [unchecked] не подавляется автоматически только в случае создания новой коллекции?

Я думаю, это было бы гораздо более сложной задачей, чем добавление <> характеристика.

UPD: я также думаю, что был бы беспорядок, если бы законно использовать сырые типы «только для нескольких вещей».

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

IMHO, имея ясный и простой способ пометить источник как Java 7, было бы более полезно, чем изобретать такие странные вещи. В таком отмеченном коде необработанные типы могут быть запрещены без потери чего-либо.

кстати., Я не думаю, что это следует делать с помощью переключателя компиляции. Java-версия файла программы является атрибутом файла, без опции вообще. Используя что-то тривиальное, как

может прояснить (вы можете предпочесть что-то более сложное, включая одно или несколько причудливых ключевых слов). Это даже позволило бы без проблем компилировать источники, написанные для разных версий Java. Это позволило бы вводить новые ключевые слова (например, «модуль») или отбрасывать некоторые устаревшие функции (несколько непубличных не вложенных классов в одном файле или что-либо еще) без потери совместимости.

Итак, лучше написать код, который не генерирует дополнительных предупреждений, а diamond operator позволяет сделать это удобным способом без ненужного повторения.

все сказанное в других ответах допустимо, но варианты использования не являются полностью допустимыми IMHO. Если один проверяет гуавы и особенно связанные с коллекциями вещи, то же самое было сделано со статическими методами. Е. Г. списки.newArrayList () что позволяет писать

или со статическим импортом

Это было бы более полезно, если бы они пошли на то, чтобы сделать поведение оператора diamond по умолчанию, то есть тип выводится с левой стороны выражения или если тип левой стороны выводился с правой стороны. Последнее происходит в Scala.

пункт для оператора Диаманта просто уменьшить печатать кода объявляя родовые типы. Это не имеет никакого влияния на время выполнения вообще.

единственная разница, если вы укажете в Java 5 и 6,

— Это, что вы должны указать @SuppressWarnings(«unchecked») до list (в противном случае вы получите непроверенное предупреждение о приведении). Насколько я понимаю, алмазный оператор пытается облегчить разработку. Ему нечего делать на выполнения дженериков в все.

Источник

Возможности Java — от Java 8 до Java 17

С момента появления в 1995 году до сегодняшнего дня в Java многое изменилось. Java 8 была революционным выпуском, вернувшим Java на пьедестал лучших языков программирования.

Эта статья сопровождается примером рабочего кода на GitHub.

Java 8

Основные изменения в выпуске Java 8:

Лямбда-выражения и Stream API

Методы по умолчанию

Лямбда-выражения и Stream API

В наших примерах мы увидим, как мы используем лямбды и потоки в различных сценариях.

Мир до лямбда-выражений

Допустим у нас есть автосалон. Чтобы избавиться от всей бумажной работы, мы хотим создать программу, которая находит все доступные в настоящее время автомобили с пробегом менее 50 000 км.

Давайте посмотрим, как наивно реализовать функцию для чего-то вроде этого:

Использование потока и лямбда-выражения

У нас та же проблема, что и в предыдущем примере.

Наш клиент хочет найти все автомобили по одинаковым критериям.

Давайте посмотрим на решение, в котором мы использовали API потока и лямбда-выражение:

Подробнее о лямбда-выражениях можно найти в документации.

Ссылка на метод

Без ссылки на метод

У нас все еще есть автосалон, и мы хотим распечатать все автомобили в магазине. Для этого мы будем использовать ссылку на метод.

Ссылка на статический метод

Ссылка на метод экземпляра объекта

Ссылка на метод экземпляра для типа

Ссылка на конструктор

Давайте посмотрим, как это сделать с помощью стандартного вызова метода:

Мы используем лямбда-выражение для вызова метода toString() на каждого объекта car.

Использование ссылки на метод

Теперь давайте посмотрим, как в той же ситуации использовать ссылку на метод:

Мы снова используем лямбда-выражение, но теперь мы вызываем метод toString() по ссылке на метод. Мы видим, насколько он лаконичнее и легче читается.

Чтобы узнать больше о справочнике по методам, посмотрите документацию.

Методы по умолчанию

Сценарий использования

Посмотрим, как выглядит наш контракт:

Добавление нового метода

Мы добавим новый метод внутрь интерфейса. Метод принимает второй аргумент с именем date, который представляет отметку времени.

Мы добавляем новый метод, но не реализуем его во всех клиентских классах. Компилятор выдаст исключение:

Использование методов по умолчанию

После добавления нового метода внутри интерфейса наш компилятор выдавал исключения. Мы собираемся решить эту проблему, используя реализацию метода по умолчанию для нового метода.

Давайте посмотрим, как создать реализацию метода по умолчанию:

Ввод ключевого слова default позволяет нам добавить реализацию метода внутри интерфейса. Теперь наш класс LoggingImplementation не завершается с ошибкой компилятора, даже если мы не реализовали новый метод внутри него.

Чтобы узнать больше о методах по умолчанию, обратитесь к документации.

Аннотации типов

определении локальной переменной

в throw и многое другое

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

Определение локальной переменной

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

Здесь мы используем аннотацию в определении локальной переменной. Обработчик аннотаций времени компиляции теперь может читать аннотацию @NotNull и выдавать ошибку, если переменной присваивается значение NULL.

Вызов конструктора

Мы хотим убедиться, что мы не можем создать пустой ArrayList :

Это прекрасный пример того, как использовать аннотации типов в конструкторе. Опять же, обработчик аннотаций может определить аннотацию и проверить, не пуст ли список массивов.

Generic тип

Инструмент может использовать рефлексию для определения аннотации и проверки того, что каждый из элементов в списке является допустимым адресом электронной почты.

Дополнительные сведения об аннотациях типов см. в документации.

Повторяющиеся аннотации

Повторяющиеся аннотации позволяют нам размещать несколько аннотаций в одном классе.

Создание повторяющейся аннотации

В этом примере мы собираемся создать повторяющуюся аннотацию под названием @Notify :

Обратите внимание, что это фиктивная аннотация только для демонстрационных целей. Эта аннотация не будет отправлять электронные письма без процессора аннотаций, который читает ее, а затем отправляет электронные письма.

Использование повторяющихся аннотаций

Мы можем добавить повторяющуюся аннотацию несколько раз к одной и той же конструкции:

У нас есть собственный класс исключений, которые мы будем генерировать всякий раз, когда пользователь пытается сделать что-то, что ему не разрешено. Наши аннотации к этому классу говорят, что мы хотим высылать уведомления в двух электронных письмах, когда код генерирует это исключение.

Чтобы узнать больше о повторяющихся аннотациях, обратитесь к документации.

Java 9

В Java 9 представлены следующие основные функции:

Система модулей Java

Diamond оператор для анонимных внутренних классов

Private методы в интерфейсах

Система модулей Java

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

Разрешения на рефлексию

Не вдаваясь в подробности, давайте создадим наш первый модуль. В нашем примере мы покажем несколько параметров и ключевых слов, которые можно использовать при создании модуля.

Создание модулей внутри IntelliJ IDEA

Сначала рассмотрим простой пример. Мы создадим приложение Hello World, в котором мы напечатаем «Hello» из одного модуля и вызываем второй модуль, чтобы вывести «World!».

Поскольку я работаю в IntelliJ IDEA, нам нужно кое-что понять в первую очередь. IntelliJ IDEA имеет концепцию модулей. Поэтому каждый модуль Java должен соответствовать одному модулю IntelliJ.

Что такое даймонд оператор java. Смотреть фото Что такое даймонд оператор java. Смотреть картинку Что такое даймонд оператор java. Картинка про Что такое даймонд оператор java. Фото Что такое даймонд оператор javaСтруктура пакета

Определение нашего первого модуля

Мы используем ключевое слово module с именем модуля для ссылки на модуль.

Можно использовать еще несколько ключевых слов:

Определение нашего второго модуля

Чтобы узнать больше о модульной системе Java, обратитесь к документации.

Try-with-resources

Закрытие ресурса вручную

Закрытие ресурса с помощью try-with-resources

Примечание переводчика. В оригинале ошибка. Оператор try-with-resources появился в Java 7. См. Java SE 7 Features and Enhancements.

Давайте посмотрим на пример использования BufferedReader для чтения строки:

Внутри блока try мы назначаем наш ранее созданной BufferedReader новой переменной. Теперь мы уверены, что наш reader всегда закрывается.

Чтобы узнать больше о try-with-resources, обратитесь к документации.

Diamond оператор для анонимных внутренних классов

До Java 9 мы не могли использовать ромбовидный оператор (<>) во внутреннем анонимном классе.

В Java 9 эта ошибка компилятора больше не возникает.

Private методы в интерфейсах

Мы уже упоминали, как мы используем методы по умолчанию в интерфейсах.

Как разделить реализацию на несколько методов? При работе с классами мы можем добиться этого с помощью private методов. Может ли это быть выходом в нашем случае?

Что касается Java 9, да. Мы можем создавать private методы внутри интерфейсов.

Использование private метода в интерфейсе

В нашем примере мы хотим напечатать набор имен.

Для интерфейса, содержащего эту функцию, определен метод по умолчанию. Мы решили, что должны, если клиент не предоставляет реализацию, предоставить набор предопределенных имен, которые мы читаем из папки ресурсов:

Мы используем BufferedReader для чтения файла, содержащего имена по умолчанию, которыми мы делимся с клиентом. Чтобы инкапсулировать наш код и, возможно, сделать его повторно используемым в других методах, мы решили переместить код для чтения и сохранения имен в List в отдельный метод. Этот метод является private, и теперь мы можем использовать его где угодно в нашем интерфейсе.

Как уже упоминалось, основным преимуществом этой функции внутри Java 9 является лучшая инкапсуляция и возможность повторного использования кода.

Java 10

Вывод типа локальной переменной

Java всегда требовала явное указание типа локальных переменных.

Тип var позволяет нам опускать тип в левой части наших операторов.

Старый способ

Давайте рассмотрим пример. Мы хотим создать небольшую группу людей, поместить все в один список, а затем просмотреть этот список в цикле for и распечатать имя и фамилию:

Это код, который мы можем видеть в большинстве случаев в Java. Мы используем явные типы, чтобы убедиться, что мы знаем, чего ожидает метод.

Неявный тип с var

Мы видим несколько наиболее типичных примеров использования типа var для локальных переменных. Во-первых, мы используем их для определения локальных переменных. Это может быть отдельный объект или даже список с ромбовидным оператором.

Дополнительные сведения о выводе типа локальной переменной см. в документации.

Java 11

Вывод типа локальной переменной в лямбда-выражениях

В Java 11 внесены улучшения в ранее упомянутый вывод типа локальной переменной. Они позволяют нам использовать тип var внутри лямбда-выражения.

Мы снова создадим несколько Person, соберем их в список и отфильтруем записи, в имени которых нет буквы «а»:

Внутри метода filter() мы используем var для вывода типа переменной вместо явного упоминания типа.

Обратите внимание, что не имеет значения, используем ли мы var или нет, вывод типа локальной переменной в лямбда-выражениях будет работать одинаково для обоих случаев.

Java 14

Switch выражения

Switch выражения позволили нам опускать break внутри каждого case блока. Это помогает улучшить читаемость и понимание кода.

В этом разделе мы увидим несколько способов использования Switch выражений.

Старый способ c оператором Switch

У нас есть метод, в котором клиент указывает желаемый месяц, а мы возвращаем количество дней в этом месяце.

Нам нужно убедиться, что мы поместили оператор break внутри каждого case блока кода. В противном случае будут проверяться другие условия после совпадения с первым.

Использование Switch выражений

Мы рассмотрим тот же пример, что и раньше. Пользователь хочет отправить месяц и получить количество дней в этом месяце:

Этот код будет делать то же самое, что и код, показанный в предыдущем примере.

Ключевое слово yield

Логика внутри case блока может быть немного сложнее, чем просто возврат значения. Например, мы хотим записать в лог, какой месяц нам отправил пользователь:

В многострочном блоке кода мы должны использовать ключевое слово yield для возврата значения из case блока.

Чтобы узнать больше об использовании Switch выражений, обратитесь к документации.

Java 15

Текстовые блоки

Текстовый блок усовершенствует форматирование строковых переменных. Начиная с Java 15, мы можем написать String, занимающую несколько строк, как обычный текст.

Пример без использования текстовых блоков

Мы хотим отправить HTML-документ по электронной почте. Мы сохраняем шаблон электронного письма в переменной:

Мы форматируем нашу строку, как в примере выше. Нам нужно позаботиться о переходе текста на новую строку и соединить все строки в одну строку.

Пример использования текстовых блоков

Давайте рассмотрим тот же пример HTML-шаблона для электронной почты. Мы хотим отправить пример электронного письма с простым форматированием HTML. На этот раз мы будем использовать текстовый блок:

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

Чтобы узнать больше о текстовых блоках, обратитесь к документации.

Java 16

Сопоставление с образцом instanceof

Сопоставление с образцом instanceof позволяет нам преобразовать нашу переменную в строку и использовать ее внутри желаемого if-else блока без явного преобразования.

Пример без сопоставления с образцом

Наш алгоритм расчета цен зависит от экземпляра автомобиля:

Поскольку мы не используем сопоставление с образцом, нам нужно преобразовать транспортное средство в правильный тип внутри каждого if-else блока. Как мы видим, это типичный пример шаблонного кода, которым славится Java.

Использование сопоставления с образцом

Давайте посмотрим, как мы можем избежать шаблонного кода в приведенном выше примере:

Следует отметить область видимости приведенной переменной. Ее видно только внутри оператора if.

Дополнительные сведения о сопоставлении с образцом в методе instanceof см. в документации.

Записи

Сколько POJO (Plain Old Java Objects) вы написали?

Что ж, могу ответить за себя: «Слишком много!».

У Java плохая репутация написания шаблонного кода. Lombok позволил нам перестать беспокоиться о геттерах, сеттерах и т. д. В Java 16 наконец-то появились Records (записи) для удаления большого количества шаблонного кода.

Обычное определение POJO

Давайте посмотрим на пример POJO класса до того, как в Java 16 были введены записи:

Он включает почти 50 строк кода для объекта, который содержит только два свойства. IDE сгенерировала этот код, но, тем не менее, он существует и должен поддерживаться.

Определение Record

Определение записи (Record) vehicle с теми же двумя свойствами может быть выполнено всего в одной строке:

В этой строке есть все те же геттеры, сеттеры, конструкторы и т. д., что и в приведенном выше примере. Следует отметить, что класс Record по умолчанию является final, и мы должны этому подчиняться. Это означает, что мы не можем расширить класс Record, но для нас доступно большинство других вещей.

Чтобы узнать больше о классах записи, обратитесь к документации.

Java 17

Sealed классы

Модификатор final в классе не позволяет никому расширить его. А как насчет того, чтобы расширить класс, но разрешить это только для некоторых классов?

Вернемся в автосалон. Мы так гордимся нашим алгоритмом расчета цен, что хотим его опубликовать. Однако мы не хотим, чтобы кто-либо использовал наше представление Vehicle. Оно справедливо только для нашего бизнеса. Здесь мы видим небольшую проблему. Нам нужно раскрыть класс, но также ограничить его.

Именно здесь в игру вступает Java 17 с запечатанными (Sealed) классами. Запечатанный класс позволяет нам сделать класс final для всех, кроме явно упомянутых классов.

Здесь нам нужно сделать еще одну вещь.

Ограничения

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

Разрешенные подклассы должны быть доступны запечатанному классу во время компиляции.

Разрешенные подклассы должны напрямую расширять запечатанный класс

Разрешенные подклассы должны иметь один из следующих модификаторов:

Разрешенные подклассы должны находиться в одном Java модуле.

Более подробную информацию о запечатанных классах можно найти в документации.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *