Final interface in Java?

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

Can an interface be declared as final in Java?

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

    Interfaces are 100% abstract and the only way to create an instance of an interface is to instantiate a class that implements it. Allowing interfaces to be final is completely pointless.

    EDIT The questions is not as outright outrageous as I first thought. A final interface is one that cannot be extended by other interfaces but can be implemented ostensibly makes sense.

    I could think of one difference between a final class and a final interface. Extending a class can compromise its integrity because it contains some state. Extending an interface simply adds operations and cannot compromise the integrity of the implementation because the interface is stateless on its own.

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

    While a final interface would still have uses, none of them are widely considered good practice.

    A final interface could be used for

    • defining constants. Generally considered a bad idea.
    • meta-information to be examined via reflection, e.g. a package descriptor
    • grouping together many public inner classes into one file. (I only suggest this is used when cut-and-pasting some sample code which has many classes as it saves you the hassle of creating a file for each class, inner classes are implicitly static)

    You can do all these things with a non-final interface and marking an interface as final would not be as useful as a comment saysing you are using an interface for an incedental purpose and why you are doing so

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

    No. The Java Language Specification section 9.1.1. Interface Modifiers states the following:

    An interface declaration may include interface modifiers.

    InterfaceModifier:
      (one of)
      Annotation public protected private
      abstract static strictfp
    

    As can be seen, the list does not include final.

    Why was the language designed this way?

    If an interface was declared final I suppose it could have meant that

    • No other interface could extend it

      This would be a non-sensical restriction. The reasons for why it can be useful to declare a class final, is to protect state invariants, prohibit overriding of all methods at once, etc. None of these restrictions makes sense for interfaces. (There is no state, and all methods must be overridden.)

    • No class could implement the interface

      This obviously defeats the purpose of an interface altogether.

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

    Whenever you create an annotation you are creating an interface that is in some ways effectively final.

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

    Instead of Declaring Interface as a Final, We can avoid Creating an Interface object.

    Point of Creating Interface to implements its methods by its subclass. If we are defeating this purpose then I feel its a baseless.

    If any have any other suggestions, kindly let us know

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

    When designing APIs in Java I sometimes find a situation where a type in the API has to be Java interface, but the number of its implementations should be limited - e.g. only the APIs internals can implement it, not anyone else.

    I realized I can now (since Java 1.6) restrict who implements an interface with the help of annotation processors (article on apidesign.org). This is the code:

    package org.apidesign.demo.finalinterface;
    
    import java.util.Collection;
    import java.util.Set;
    import javax.annotation.processing.AbstractProcessor;
    import javax.annotation.processing.Processor;
    import javax.annotation.processing.RoundEnvironment;
    import javax.annotation.processing.SupportedAnnotationTypes;
    import javax.lang.model.element.Element;
    import javax.lang.model.element.TypeElement;
    import javax.lang.model.type.TypeMirror;
    import javax.tools.Diagnostic;
    import org.openide.util.lookup.ServiceProvider;
    
    @ServiceProvider(service = Processor.class)
    @SupportedAnnotationTypes("*")
    public final class FinalEnforcingProcessor extends AbstractProcessor {
        @Override
        public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
            checkForViolations(roundEnv.getRootElements());
            return true;
        }
    
        private void checkForViolations(Collection<? extends Element> all) {
            for (Element e : all) {
                if (e instanceof TypeElement) {
                    TypeElement te = (TypeElement) e;
    /* exception for the only known implementation:
    if ("org.apidesign.demo.finalinterface.AllowedImplementationTest".equals(
      te.getQualifiedName().toString())
    ) continue;
    */
                    for (TypeMirror m : te.getInterfaces()) {
                        if (FinalInterface.class.getName().equals(m.toString())) {
                            processingEnv.getMessager().printMessage(
                              Diagnostic.Kind.ERROR, "Cannot implement FinalInterface", e
                            );
                        }
                    }
                }
                checkForViolations(e.getEnclosedElements());
            }
        }
     }
    

    Everytime somebody includes your API JAR on classpath and tries to compile against it, the Javac compiler invokes your annotation processor and let's you fail the compilation if it detects somebody else is trying to implement your interface.

    I still prefer usage of final class for Client API - e.g. an API that others are only allowed to call, but when it is not possible, the trick with annotation processor is acceptable alternative.

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