Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Final arguments in interface methods - what's the point?

People also ask

Why should method parameters be final?

Having final on methods parameters helps you understand the outgoings of the method at first glance, and draws some attention to those non-final parameters.

Why methods in interface are final?

If you make a method final you cannot override it and, if you make a variable final you cannot modify it. i.e. use final with Java entities you cannot modify them further. If you make an interface final, you cannot implement its methods which defies the very purpose of the interfaces.

Can method be final in interface?

No.An interface must not have an final method. No ;Interface only have abstract methods.

What is a final argument in Java?

The final keyword when used for parameters/variables in Java marks the reference as final. In case of passing an object to another method, the system creates a copy of the reference variable and passes it to the method. By marking the new references final, you protect them from reassignment.


It doesn't seem like there's any point to it. According to the Java Language Specification 4.12.4:

Declaring a variable final can serve as useful documentation that its value will not change and can help avoid programming errors.

However, a final modifier on a method parameter is not mentioned in the rules for matching signatures of overridden methods, and it has no effect on the caller, only within the body of an implementation. Also, as noted by Robin in a comment, the final modifier on a method parameter has no effect on the generated byte code. (This is not true for other uses of final.)


Some IDEs will copy the signature of the abstract/interface method when inserting an implementing method in a sub class.

I don't believe it makes any difference to the compiler.

EDIT: While I believe this was true in the past, I don't think current IDEs do this any more.


Final annotations of method parameters are always only relevant to the method implementation never to the caller. Therefore, there is no real reason to use them in interface method signatures. Unless you want to follow the same consistent coding standard, which requires final method parameters, in all method signatures. Then it is nice to be able to do so.


Update: Original answer below was written without fully understanding the question, and therefore does not directly address the question :) Nevertheless, it must be informative for those looking to understand the general use of final keyword.

As for the question, I would like to quote my own comment from below.

I believe you're not forced to implement the finality of an argument to leave you free to decide whether it should be final or not in your own implementation.

But yes, it sounds rather odd that you can declare it final in the interface, but have it non-final in the implementation. It would have made more sense if either:

a. final keyword was not allowed for interface (abstract) method arguments (but you can use it in implementation), or
b. declaring an argument as final in interface would force it to be declared final in implementation (but not forced for non-finals).


I can think of two reasons why a method signature can have final parameters: Beans and Objects (Actually, they are both the same reason, but slightly different contexts.)

Objects:

public static void main(String[] args) {
    StringBuilder cookingPot = new StringBuilder("Water ");
    addVegetables(cookingPot);
    addChicken(cookingPot);
    System.out.println(cookingPot.toString());
    // ^--- OUTPUT IS: Water Carrot Broccoli Chicken ChickenBroth 
    //      We forgot to add cauliflower. It went into the wrong pot.
}

private static void addVegetables(StringBuilder cookingPot) {
    cookingPot.append("Carrot ");
    cookingPot.append("Broccoli ");
    cookingPot = new StringBuilder(cookingPot.toString());
    //   ^--- Assignment allowed...
    cookingPot.append("Cauliflower ");
}

private static void addChicken(final StringBuilder cookingPot) {
    cookingPot.append("Chicken ");
    //cookingPot = new StringBuilder(cookingPot.toString());
    //     ^---- COMPILATION ERROR! It is final.
    cookingPot.append("ChickenBroth ");
}

The final keyword ensured that we will not accidentally create a new local cooking pot by showing a compilation error when we attempted to do so. This ensured the chicken broth is added to our original cooking pot which the addChicken method got. Compare this to addVegetables where we lost the cauliflower because it added that to a new local cooking pot instead of the original pot it got.

Beans: It is the same concept as objects (as shown above). Beans are essentially Objects in Java. However, beans (JavaBeans) are used in various applications as a convenient way to store and pass around a defined collection of related data. Just as the addVegetables could mess up the cooking process by creating a new cooking pot StringBuilder and throwing it away with the cauliflower, it could also do the same with a cooking pot JavaBean.