В чем смысл интерфейса маркеров в java и почему мы не можем обойтись без них?

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

Я ищу в Интернете, и все ответы примерно такие: «они предоставляют некоторую важную информацию для JVM, чтобы JVM могла выполнять некоторые полезные операции», но вопрос в том, почему JVM должна это знать и какую возможную операцию выполняет JVM должен выполнить? Почему я не могу просто клонировать объект, не расширяя класс из Clonable? Почему я не могу сериализовать объект класса, не расширяя его из Serializable?

Маркерные интерфейсы не имеют особого смысла и, на мой взгляд, это явно не лучший дизайн. Интерфейс БЕЗ каких-либо методов ??? В чем смысл?

Теперь, по-видимому, здесь должна использоваться аннотация вместо интерфейса маркера, но все же вопрос в том, почему JVM должна знать?


person Uzair Abid    schedule 29.10.2019    source источник
comment
цель интерфейса «маркер» - «пометить» классы. Например, класс, который не реализует Serializable ни прямо, ни косвенно, не может быть сериализован. ... и почему мы не можем жить без них? Мы можем, мы делаем. В некоторых случаях, чтобы сохранить обратную совместимость, старые все еще требуются, но нет причин создавать новые. ... не имеет особого смысла ... на самом деле, когда вы понимаете концепцию, они понимают.   -  person Stultuske    schedule 29.10.2019
comment
Почему я не могу просто клонировать объект, не расширяя класс из Clonable? Вы могли бы это сделать, если бы язык был разработан таким образом. Но что означало бы клонировать дескриптор файла? Или синглтон? Некоторые вещи следует клонировать, другие - нет; нет очевидного способа определить это, не сообщая JVM.   -  person Andy Turner    schedule 29.10.2019
comment
@Stultuske, да, в этом есть смысл, если так выразиться.   -  person Uzair Abid    schedule 29.10.2019
comment
@AndyTurner, я понял вашу точку зрения   -  person Uzair Abid    schedule 29.10.2019


Ответы (4)


Вы четко понимаете, что делают интерфейсы маркеров. Ты сам так сказал!

Так зачем они нам все еще нужны?

В каком-то смысле они нам не нужны. Все, что вы можете выразить с помощью интерфейсов маркеров, вы можете выразить с помощью аннотаций. Нет сомнений в том, что аннотации - лучший способ решить проблему.

Основная причина, по которой у нас (все еще) есть интерфейсы маркеров, - История:

  • Аннотации Java были добавлены в язык Java в Java 5.0. До этого лучшим доступным решением были маркерные интерфейсы.

  • Удаление интерфейсов маркеров из класса нарушает бинарную совместимость.

  • Существует небольшое количество интерфейсов маркеров Java SE, которые предшествовали Java 5.0 и широко используются в пользовательском коде. На ум приходят два Serializable и Cloneable.

Нравится нам это или нет, но в Java есть маркерные интерфейсы, и это вряд ли изменится.


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

Ну да. С точки зрения 2019 года это правда.

С точки зрения 1997 года, когда Java была новой, а до C # оставалось 5 лет, единственными распространенными (-ish) языками с чем-то вроде аннотаций были версии LISP.

Теперь я почти уверен, что разработчики библиотеки классов Java еще в эпоху Java 1.0 знали, что интерфейсы маркеров были ошибочной идеей. Но у них не было альтернативы. Это было использование интерфейсов-маркеров или откладывание разработки и реализации некоторых хороших фундаментальных API-интерфейсов Java на 5 или более лет.

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

person Stephen C    schedule 29.10.2019
comment
Еще есть аннотации маркеров как @Configuration zetcode.com/spring/configuration - person user7294900; 29.10.2019
comment
@ user7294900 - Ну да ... но все аннотации в каком-то смысле маркеры. И это не проблема, потому что аннотации предназначены именно для этого. - person Stephen C; 29.10.2019

Вам не нужно реализовывать Serializable для сериализации или Cloneable для клонирования. Суть этих интерфейсов в том, что Java имеет встроенные механизмы для клонирования и сериализации, и вам нужно реализовать эти интерфейсы только в том случае, если вы хотите использовать эти встроенные механизмы.

Таким образом, просто реализовав Serializable, вы автоматически сможете использовать этот класс с ObjectInputStream и ObjectOutputStream без какого-либо дополнительного кода.

Клонируемый, с другой стороны, я считаю практически бесполезным. Обычно вы просто реализуете Cloneable, переопределяете Object.clone и делаете его общедоступным, и вы мгновенно получаете клонирование. Но говорят, что он сломан, и вам лучше просто написать собственную логику клонирования, например, с помощью конструктора копирования.

person Leo Aso    schedule 29.10.2019

Точки, которые любой класс может реализовать без добавления каких-либо дополнительных методов / полей / накладных расходов

Вы просто помечаете класс, и он готов к использованию / сериализации.

Даже после Java 5.0, где были введены аннотации,

Еще есть аннотации маркеров в виде @Configuration

Аннотация @Configuration используется для конфигурации на основе аннотаций Spring. @Configuration - это аннотация маркера, которая указывает, что класс объявляет один или несколько методов @Bean и может обрабатываться контейнером Spring для создания определений bean-компонентов и запросов на обслуживание для этих bean-компонентов во время выполнения.

person user7294900    schedule 29.10.2019
comment
привет, вот в чем вопрос, как я уже сказал, в Интернете люди говорят, что мы помечаем его и используем, и это нормально, но зачем помечать его для JVM. Что делает JVM, когда мы ее отмечаем. Я ищу более скрытую причину, если вы понимаете, о чем я. Должна быть причина, но что это такое, я не могу это представить - person Uzair Abid; 29.10.2019
comment
@UzairAbid Как JVM будет определять определенные классы? по полю / имени класса / родительскому классу / ... параметры, которые менее желательны / расширяемы, можете ли вы предложить другой способ, как JVM должна находить классы? - person user7294900; 29.10.2019

Я могу ответить на ваш частичный вопрос - В чем смысл интерфейса маркера в java?

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

Так в чем же ключевая разница?

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

Например, добавим ограничение, что из базы данных можно удалить только тип Shape:

public interface Shape {
    double getArea();
    double getCircumference();
}

В этом случае интерфейс нашего маркера, назовем его DeletableShape, будет выглядеть следующим образом:

public interface DeletableShape extends Shape {
}

Затем наш класс будет реализовывать интерфейс маркера:

public class Rectangle implements DeletableShape {
    // implementation details
}

Следовательно, все реализации DeletableShape также являются реализациями Shape. Очевидно, мы не можем сделать это с помощью аннотаций.

Однако каждое дизайнерское решение имеет компромиссы, и полиморфизм может использоваться как контраргумент против интерфейсов маркеров. В нашем примере каждый класс, расширяющий Rectangle, автоматически реализует DeletableShape.


Это может не дать точного ответа на ваш запрос. Но может частично помочь вам.

Источник: baeldung.com

person ajinzrathod    schedule 26.07.2021