Michael Laffargue
Michael Laffargue

Reputation: 10304

Use of "final" for method parameter in Java

I read with interest this question : Can I pass parameters by reference in Java?

What comes out it is that parameters (which are not primitives) are passed by copying the reference value. And so as the example states; you can't modify the reference of the parameter you gave:

Object o = "Hello";
mutate(o)
System.out.println(o); // Will print Hello

private void mutate(Object o) { o = "Goodbye"; } //NOT THE SAME o!

This kind of problem could be avoided using finallike this :

private void mutate(final Object o) { o = "Goodbye"; } //Compilation error

The questions :

I rarely used final for method parameters in Java but now I can't think of any case where you would voluntarily omit to put final to a method parameter.

Thanks!

Upvotes: 3

Views: 1455

Answers (5)

Francisco Spaeth
Francisco Spaeth

Reputation: 23903

To avoid this:

public void searchBiggest(String startingWith) {
    for (String s : collection) {
        if (s.startsWith(startingWith)) {
            startingWith = s;
        }
    }
    return startingWith;
}

As you can see it makes the code not intuitive because the parameter could be holding a different value that the one passed.

From Hard Core Java - Chapter 2:

Little bugs like this are often the most difficult to locate. By Murphy’s Law, you can absolutely guarantee that this code will be in the middle of a huge piece of your project, and the error reports won’t directly lead you here. What’s more, you proba- bly won’t notice the impact of the bug until it goes into production and users are screaming for a fix.

You cannot afford to forget that once you write code, the story is not over. People will make changes, additions, and errors in your code. You will have to look through the code and fix everything that was messed up. To prevent this problem from occur- ring, do the following:

and a similar sample is done using the parameter, and additionally invoking other methods with the parameter (already changed).

Upvotes: 4

Kumar Vivek Mitra
Kumar Vivek Mitra

Reputation: 33534

1. You are passing the Object Reference Variable as the Argument, when you invoked the method by calling it.

    mutate(o);

2. By using the final keyword on the Parameter in the Method Definition, you have made it final, So it means that local Object Reference Variable o which is of type Object is final, so this variable can't be used to point any other object.

(Note: Its the Object Reference Variable which is final, Not the Object on the HEAP)

mutate(final Object o)

3. You can assign the object associated with the Object Reference Variable o to some other Object Reference Variable and then change it.

Object i = o;
 i = "GoodBye";

Upvotes: 2

Brian Agnew
Brian Agnew

Reputation: 272297

I usually do this to prevent accidental or unintended modifications of this reference. e.g.

private String doSomething(final String arg) {
   // final to prevent me doing something stupid!
}

One interesting scenario is in setters. You want to ensure that you set the member variable and not the arg passed in. e.g.

public void setArg(String arg) {
   _arg = arg;
}

In the above scenario, if the method parameter is not final, then I could possibly set

   arg = arg;

by mistake. The above is a common typo, or can occur due to search/replace refactoring. By making arg final, you can't accidentally reassign it.

Upvotes: 4

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340743

Typically you shouldn't modify parameters as it can introduce hard to find bugs. However there are some useful idioms and situations where it can be useful:

public void print(String msg, int count) {
    msg = (msg != null)? msg : "Default";
    while(--count >= 0) {
        System.out.println(msg);
    }
}

Upvotes: 2

pauljwilliams
pauljwilliams

Reputation: 19225

Java passes by value. So when you call mutate, a copy of o is passed.

Inside mutate, the copy of o is then set to point to "Goodbye". The original o is unchanged.

Setting the parameter to be final will not change this, but it will, as you've seen, stop reassignment of the copy of the original reference. Thats not the same, however, as stopping reassignment of the original reference.

Upvotes: 2

Related Questions