Search code examples
javainheritancefinal

When I define an interface method's parameters final do I need to repeat final in the implementations?


So do I need to repeat final in the case below ?

interface Foo {

    void meth(final Bar bar);
}

public Baz implements Foo {

    @Override
    void meth(/* is it final ?*/ Bar bar){}
}

The question is not only for interface inheritance but class inheritance also - I guess the answer will be the same


Solution

  • Yes you do need to redeclare method parameters as final if you want the compiler to make sure these parameters are never reassigned in the current method. This holds both when overriding interface and class definitions.

    The reason for this is rather simple: This is the behavior specified in the Java language specification. However, the compiler could not even check for not reassigning final parameters even if it wanted to:

    The final modifier for variables in method scope is actually not translated into byte code or written elsewhere into the Java class file format. It basically disappears after the compilation of a specific class or interface and cannot be traced after this compilation. Since each class and interface is compiled independently of other classes and interfaces, the compiler or the JVM run time verifier could not make sure that final parameters were assigned with a new value in subclasses or interface implementations. It is only within the compilation of a single class where the Java compiler can assure that such assignments do not occure. The declaration of final parameters is therefore local for a class and it would not be possibility to change this behavior in the future or to find out about this feature by using run time reflection.

    Using a final parameter in an abstract method signature does therefore not serve a purpose, neither a real one or a documentary one: Since Java implements method calls by call by value and not by reference, the final modifier will never effect code outside of the implementing method's scope. If a method parameter variable is reassigned is therefore merely a detail of the methods actual implementation. I would therefore personally never use it for defining abstract methods in classes or interfaces. It is allowed but meaningless.

    Within non-abstract method definitions, declaring a method variable final only serves one of two purposes:

    • You want to use a variable inside an anonymous class's scope.
    • You want the compiler to check that you did not accidentaly reassign a variable. This is escpecially useful when dealing with many variables of similar type. Here, the final modifier also serves as some kind of documentation.

    UPDATE: Since Java 8, a method parameter is attributed on if it is synthetic (non represented in the source code, mandated (implicitly present in the source code, e.g. the this reference for lambda expressions) or if it is final. This does however not effect overridden methods where the final declaration needs to be repeated for this flag to be set. Furthermore does the Java language not pay attention to these flags, it is only meta frameworks that read these flags to implement their logic which might react to theses flags.