Can an interface be declared as final in Java?
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.
Compile a non final interface. I saved the below code in FinalInterface.java. Then I compiled it.
interface FinalInterface { }
Run BCELifier on it. This created a file called FinalInterfaceCreator.java
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[] { });
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?