final keyword in method parameters

JavaFinal

Java Problem Overview


I often encounter methods which look like the following:

public void foo(final String a, final int[] b, final Object1 c){
}

What happens if this method is called without passing it final parameters. i.e. an Object1 that is later changed (so is not declared as final) can be passed to this method just fine

Java Solutions


Solution 1 - Java

Java always makes a copy of parameters before sending them to methods. This means the final doesn't mean any difference for the calling code. This only means that inside the method the variables can not be reassigned.

Note that if you have a final object, you can still change the attributes of the object. This is because objects in Java really are pointers to objects. And only the pointer is copied (and will be final in your method), not the actual object.

Solution 2 - Java

There is a circumstance where you're required to declare it final --otherwise it will result in compile error--, namely passing them through into anonymous classes. Basic example:

public FileFilter createFileExtensionFilter(final String extension) {
    FileFilter fileFilter = new FileFilter() {
        public boolean accept(File pathname) {
            return pathname.getName().endsWith(extension);
        }
    };

    // What would happen when it's allowed to change extension here?
    // extension = "foo";

    return fileFilter;
}

Removing the final modifier would result in compile error, because it isn't guaranteed anymore that the value is a runtime constant. Changing the value from outside the anonymous class would namely cause the anonymous class instance to behave different after the moment of creation.

Solution 3 - Java

Java is only pass-by-value. (or better - pass-reference-by-value)

So the passed argument and the argument within the method are two different handlers pointing to the same object (value).

Therefore if you change the state of the object, it is reflected to every other variable that's referencing it. But if you re-assign a new object (value) to the argument, then other variables pointing to this object (value) do not get re-assigned.

Solution 4 - Java

The final keyword on a method parameter means absolutely nothing to the caller. It also means absolutely nothing to the running program, since its presence or absence doesn't change the bytecode. It only ensures that the compiler will complain if the parameter variable is reassigned within the method. That's all. But that's enough.

Some programmers (like me) think that's a very good thing and use final on almost every parameter. It makes it easier to understand a long or complex method (though one could argue that long and complex methods should be refactored.) It also shines a spotlight on method parameters that aren't marked with final.

Solution 5 - Java

Consider this implementation of foo():

public void foo(final String a) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            System.out.print(a);
        }
    }); 
}

Because the Runnable instance would outlive the method, this wouldn't compile without the final keyword -- final tells the compiler that it's safe to take a copy of the reference (to refer to it later). Thus, it's the reference that's considered final, not the value. In other words: As a caller, you can't mess anything up...

Solution 6 - Java

final means you can't change the value of that variable once it was assigned.

Meanwhile, the use of final for the arguments in those methods means it won't allow the programmer to change their value during the execution of the method. This only means that inside the method the final variables can not be reassigned.

Solution 7 - Java

If you declare any parameter as final, you cannot change the value of it.

class Bike11 {  
    int cube(final int n) {  
        n=n+2;//can't be changed as n is final  
        n*n*n;  
     }  
    public static void main(String args[]) {  
        Bike11 b=new Bike11();  
        b.cube(5);  
    }  
}   

Output: Compile Time Error

For more details, please visit my blog: http://javabyroopam.blogspot.com

Solution 8 - Java

final keyword in the method input parameter is not needed. Java creates a copy of the reference to the object, so putting final on it doesn't make the object final but just the reference, which doesn't make sense

Solution 9 - Java

Strings are immutable, so actully you can't change the String afterwards (you can only make the variable that held the String object point to a different String object).

However, that is not the reason why you can bind any variable to a final parameter. All the compiler checks is that the parameter is not reassigned within the method. This is good for documentation purposes, arguably good style, and may even help optimize the byte code for speed (although this seems not to do very much in practice).

But even if you do reassign a parameter within a method, the caller doesn't notice that, because java does all parameter passing by value. After the sequence

  a = someObject();
  process(a);

the fields of a may have changed, but a is still the same object it was before. In pass-by-reference languages this may not be true.

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
QuestionAlyView Question on Stackoverflow
Solution 1 - JavaThirlerView Answer on Stackoverflow
Solution 2 - JavaBalusCView Answer on Stackoverflow
Solution 3 - JavaBozhoView Answer on Stackoverflow
Solution 4 - JavaErick G. HagstromView Answer on Stackoverflow
Solution 5 - JavaRahel LüthyView Answer on Stackoverflow
Solution 6 - JavaSilentKnightView Answer on Stackoverflow
Solution 7 - JavaRoopamView Answer on Stackoverflow
Solution 8 - JavattatiView Answer on Stackoverflow
Solution 9 - JavaKilian FothView Answer on Stackoverflow