Why private method can not be final as well?

JavaOopMethodsFinal

Java Problem Overview


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?)

Java Solutions


Solution 1 - Java

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.

Solution 2 - Java

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: https://stackoverflow.com/questions/7728971/java-safevarargs-why-do-private-methods-need-to-be-final

Solution 3 - Java

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMightyPorkView Question on Stackoverflow
Solution 1 - JavayshavitView Answer on Stackoverflow
Solution 2 - Javajaco0646View Answer on Stackoverflow
Solution 3 - JavaMcDowellView Answer on Stackoverflow