Final interface in Java?

前端 未结 10 2085
情话喂你
情话喂你 2020-12-03 09:37

Can an interface be declared as final in Java?

相关标签:
10条回答
  • 2020-12-03 10:29

    No. Trying to declare an interface as final in Java results in a compilation error. This is a language design decision - Java interfaces are meant to be extendable.

    0 讨论(0)
  • 2020-12-03 10:34

    final means it can't be modified. If it's a class, it can't be modified by extending (methods can be modified by overriding, attribute's can't be modified; added attributes/methods can only be accessed as members of the 'subclass type'); if its a variable (attribute/local) then the value can't be modified after first assignment; if its a method, the implementation can't be modified (a final method can be overloaded but can't be overridden). There no point in declaring an interface final since there's normally no implementation to modify (default and static interface methods are not allowed to be final).

    0 讨论(0)
  • 2020-12-03 10:36

    From the Java Language Specification (Third Edition):

    9.1.1.1 abstract Interfaces

    Every interface is implicitly abstract. This modifier is obsolete and should not be used in new programs.

    So, abstract + final is sort of an oxymoron.

    0 讨论(0)
  • 2020-12-03 10:37

    I tried it and apparently you can create a final interface in java. I have no idea why you would do this, but you can. This is how I did it.

    1. Compile a non final interface. I saved the below code in FinalInterface.java. Then I compiled it.

      interface FinalInterface { }

    2. Run BCELifier on it. This created a file called FinalInterfaceCreator.java

    3. Edit it. Look for a line similar to below and add ACC_FINAL.

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

    4. Compile and run the edited FinalInterfaceCreator.java. This should overwrite the original FinalInterface.class file with a new one that is similar but final.

    To test it, I created two new java files TestInterface and TestClass. TestInterface is an interface that extends FinalInterface and TestClass is a class that implements FinalInterface. The compiler refused to compile either because FinalInterface is final.

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

    In addition, I tried creating an instance of FinalInterface using dynamic proxies

    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 ) ) ;
        }
    }
    

    This one compiled but did not run

    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)
    

    So the evidence suggests that you can create a final interface in java, but why would you want to?

    0 讨论(0)
提交回复
热议问题