Заключительный интерфейс в Java?

Интерфейс может быть объявлен как финал в Java?

31
задан aioobe 27 September 2011 в 10:56
поделиться

8 ответов

Интерфейсы на 100% абстрактны, и единственный способ создать экземпляр интерфейса - это инстанцировать класс, который его реализует. Разрешение интерфейсам быть конечными совершенно бессмысленно.

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

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

22
ответ дан 27 November 2019 в 22:08
поделиться

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

Последний интерфейс может использоваться для

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

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

2
ответ дан 27 November 2019 в 22:08
поделиться

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

-1
ответ дан 27 November 2019 в 22:08
поделиться

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

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

Если у кого-то есть другие предложения, пожалуйста, дайте нам знать

-1
ответ дан 27 November 2019 в 22:08
поделиться

Нет. Раздел Спецификации языка Java 9.1.1. Модификаторы интерфейса заявляют следующее:

Объявление интерфейса может включать модификаторы интерфейса.

 InterfaceModifier:
 (один из)
Аннотации публично защищенные частные
абстрактный статический strictfp

Как видно, список не включает final .

Почему язык был разработан таким образом?

Если бы интерфейс был объявлен окончательным , я полагаю, это могло означать, что

  • Никакой другой интерфейс не мог бы его расширить.

    Это было бы не -смысловое ограничение. Причины, по которым может быть полезно объявить класс final, - это защита инвариантов состояния, запрет одновременного переопределения всех методов и т. Д. Ни одно из этих ограничений не имеет смысла для интерфейсов. (Состояние отсутствует, и все методы должны быть переопределены.)

  • Ни один класс не может реализовать интерфейс

    Это, очевидно, полностью сводит на нет цель интерфейса.

11
ответ дан 27 November 2019 в 22:08
поделиться

Из спецификации языка Java (третье издание):

9.1.1.1 абстрактные интерфейсы

Каждый интерфейс неявно абстракция. Этот модификатор устарел и не должны использоваться в новых Программ.

Таким образом, abstract + final — это своего рода оксюморон.

8
ответ дан 27 November 2019 в 22:08
поделиться

Нет. Попытка объявить интерфейс окончательным в Java приводит к ошибке компиляции. Это решение о проектировании языка - интерфейсы Java предназначены для расширения.

15
ответ дан 27 November 2019 в 22:08
поделиться

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

  1. Скомпилировать не финальный интерфейс. Я сохранил приведенный ниже код в FinalInterface.java. Потом я его скомпилировал.

    интерфейс FinalInterface { }

  2. Запустите на нем BCELifier. В результате был создан файл FinalInterfaceCreator.java

  3. Отредактируйте его. Найдите строку, подобную приведенной ниже, и добавьте ACC_FINAL.

    _cg = new ClassGen ("FinalInterface", "java.lang.Object", "FinalInterface.java", ACC_INTERFACE | ACC_ABSTRACT | ACC_FINAL, new String [] {});

  4. Скомпилируйте и запустите отредактированный FinalInterfaceCreator. Джава. Это должно заменить исходный файл FinalInterface.class новым, похожим, но окончательным.

Чтобы проверить это, я создал два новых java-файла TestInterface и TestClass. TestInterface - это интерфейс, расширяющий FinalInterface, а TestClass - это класс, реализующий FinalInterface. Компилятор отказался компилировать либо потому, что FinalInterface является окончательным.

TestClass.java:2: cannot inherit from final FinalInterface
class TestClass implements FinalInterface

TestInterface.java:2: cannot inherit from final FinalInterface
interface TestInterface extends FinalInterface

Кроме того, я попытался создать экземпляр FinalInterface с использованием динамических прокси

class Main
{
    public static void main ( String [ ] args )
    {
    Class < ? > ntrfc = FinalInterface . class ;
    ClassLoader classLoader = ntrfc . getClassLoader ( ) ;
    Class < ? > [ ] interfaces = { ntrfc } ;
    java . lang . reflect . InvocationHandler invocationHandler = new java . lang . reflect . InvocationHandler ( )
        {
        public Object invoke ( Object proxy , java . lang . reflect . Method method , Object [ ] args )
        {
            return ( null ) ;
        }
        } ;
    FinalInterface fi = ( FinalInterface ) ( java . lang . reflect . Proxy . newProxyInstance ( classLoader , interfaces , invocationHandler ) ) ;
    }
}

Этот был скомпилирован, но не запущен

Exception in thread "main" java.lang.ClassFormatError: Illegal class modifiers in class FinalInterface: 0x610
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:632)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:277)
at java.net.URLClassLoader.access$000(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:212)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:319)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:264)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:332)
at Main.main(Main.java:6)

Итак, данные свидетельствуют о том, что вы можете создать окончательный интерфейс на java, но зачем вам это нужно?

4
ответ дан 27 November 2019 в 22:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: