Интерфейс может быть объявлен как финал в Java?
Интерфейсы на 100% абстрактны, и единственный способ создать экземпляр интерфейса - это инстанцировать класс, который его реализует. Разрешение интерфейсам быть конечными
совершенно бессмысленно.
EDIT Вопросы не настолько возмутительны, как мне показалось. Окончательный интерфейс - это тот, который не может быть расширен другими интерфейсами, но может быть реализован, что якобы имеет смысл.
Я могу назвать одно различие между конечным классом и конечным интерфейсом. Расширение класса может нарушить его целостность, поскольку он содержит некоторое состояние. Расширение интерфейса просто добавляет операции и не может нарушить целостность реализации, потому что интерфейс сам по себе не имеет состояния.
Хотя окончательный интерфейс все еще будет иметь применение, ни один из них не считается хорошей практикой.
Последний интерфейс может использоваться для
Вы можете делать все это с помощью неокончательного интерфейса, и пометка интерфейса как окончательного не была бы так полезна, как комментарий, в котором говорится, что вы используете интерфейс для инцедентальной цели и почему вы это делаете так
Всякий раз, когда вы создаете аннотацию, вы создаете интерфейс, который в некотором смысле является конечным.
Вместо объявления интерфейса конечным, мы можем избежать создания объекта интерфейса.
Пункт создания интерфейса для реализации своих методов с помощью своего подкласса. Если мы проигрываем эту цель, я считаю ее безосновательной.
Если у кого-то есть другие предложения, пожалуйста, дайте нам знать
Нет. Раздел Спецификации языка Java 9.1.1. Модификаторы интерфейса заявляют следующее:
Объявление интерфейса может включать модификаторы интерфейса.
InterfaceModifier: (один из) Аннотации публично защищенные частные абстрактный статический strictfp
Как видно, список не включает final
.
Если бы интерфейс был объявлен окончательным
, я полагаю, это могло означать, что
Никакой другой интерфейс не мог бы его расширить.
Это было бы не -смысловое ограничение. Причины, по которым может быть полезно объявить класс final, - это защита инвариантов состояния, запрет одновременного переопределения всех методов и т. Д. Ни одно из этих ограничений не имеет смысла для интерфейсов. (Состояние отсутствует, и все методы должны быть переопределены.)
Ни один класс не может реализовать интерфейс
Это, очевидно, полностью сводит на нет цель интерфейса.
Из спецификации языка Java (третье издание):
9.1.1.1 абстрактные интерфейсы
Каждый интерфейс неявно
абстракция
. Этот модификатор устарел и не должны использоваться в новых Программ.
Таким образом, abstract
+ final
— это своего рода оксюморон.
Нет. Попытка объявить интерфейс окончательным в Java приводит к ошибке компиляции. Это решение о проектировании языка - интерфейсы Java предназначены для расширения.
Я попробовал и, по-видимому, вы можете создать окончательный интерфейс на java. Понятия не имею, зачем вы это сделали, но можете. Вот как я это сделал.
Скомпилировать не финальный интерфейс. Я сохранил приведенный ниже код в FinalInterface.java. Потом я его скомпилировал.
интерфейс FinalInterface { }
Запустите на нем BCELifier. В результате был создан файл FinalInterfaceCreator.java
Отредактируйте его. Найдите строку, подобную приведенной ниже, и добавьте ACC_FINAL.
_cg = new ClassGen ("FinalInterface", "java.lang.Object", "FinalInterface.java", ACC_INTERFACE | ACC_ABSTRACT | ACC_FINAL, new String [] {});
Скомпилируйте и запустите отредактированный 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, но зачем вам это нужно?