55

Is it redundant to add private and final to a same method?

class SomeClass {

    //--snip--

    private final void doStuff()
    {
        // private work here
    }
}

If it's private, there's no way anyone can override it, right?

Why is it possible to add final keyword if it has no effect? (or am I missing something?)

5

3 Answers 3

64

Basically, it's allowed because they didn't feel like it's worthwhile to put a special case prohibiting the private modifier. It's like how you can also declare methods on an interface as public, or nested classes in an interface as static, even though those keywords are implied in interfaces. You can also declare final methods on a final class, etc.

Java took the stance of not complaining when you add redundant modifiers. They do it consistently.

1
  • In addition, code inspection "complains" about this.
    – Delfic
    Commented May 31, 2016 at 14:21
5

One edge case that requires a private method to be final is when the SafeVarargs annotation is used. The following code does not compile, because the private method is not final.

@SafeVarargs
private void method(List<String>... stringLists) {
    //TODO a safe varargs operation
}

This was fixed in Java 9.
See: java @SafeVarargs why do private methods need to be final

0
4

It makes the language more flexible but the language does not guarantee that it will have any effect. Making a private method final is a hint to the (JIT) compiler.

The Java Language Specification notes that:

A method can be declared final to prevent subclasses from overriding or hiding it.

It is a compile-time error to attempt to override or hide a final method.

A private method and all methods declared immediately within a final class (§8.1.1.2) behave as if they are final, since it is impossible to override them.

At run time, a machine-code generator or optimizer can "inline" the body of a final method, replacing an invocation of the method with the code in its body. The inlining process must preserve the semantics of the method invocation. In particular, if the target of an instance method invocation is null, then a NullPointerException must be thrown even if the method is inlined. A Java compiler must ensure that the exception will be thrown at the correct point, so that the actual arguments to the method will be seen to have been evaluated in the correct order prior to the method invocation.

From Wikipedia:

A common misconception is that declaring a class or method as final improves efficiency by allowing the compiler to directly insert the method wherever it is called (see inline expansion). But because the method is loaded at runtime, compilers are unable to do this. Only the runtime environment and JIT compiler know exactly which classes have been loaded, and so only they are able to make decisions about when to inline, whether or not the method is final

Machine code compilers which generate directly executable, platform-specific machine code, are an exception. When using static linking, the compiler can safely assume that methods and variables computable at compile-time may be inlined.

1
  • 5
    Since private methods are treated as final, you don't need "final" on them to give JIT a hint that they can be inlined. Your answer suggests using private final might be advantageous, but the text you quote says otherwise.
    – Kevin
    Commented Mar 18, 2016 at 14:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.