Making java method arguments as final

66,539

Solution 1

As a formal method parameter is a local variable, you can access them from inner anonymous classes only if they are declared as final.

This saves you from declaring another local final variable in the method body:

 void m(final int param) {
        new Thread(new Runnable() {
            public void run() {
                System.err.println(param);
            }
        }).start();
    }

Solution 2

Extract from The final word on the final keyword

Final Parameters

The following sample declares final parameters:

public void doSomething(final int i, final int j)
{
  // cannot change the value of i or j here...
  // any change would be visible only inside the method...
}

final is used here to ensure the two indexes i and j won't accidentally be reset by the method. It's a handy way to protect against an insidious bug that erroneously changes the value of your parameters. Generally speaking, short methods are a better way to protect from this class of errors, but final parameters can be a useful addition to your coding style.

Note that final parameters are not considered part of the method signature, and are ignored by the compiler when resolving method calls. Parameters can be declared final (or not) with no influence on how the method is overriden.

Solution 3

The final prevents you from assigning a new value to the variable, and this can be helpful in catching typos. Stylistically you might like to keep the parameters received unchanged and assign only to local variables, so final would help to enforce that style.

Must admit I rarely remember to use final for parameters, maybe I should.

public int example(final int basicRate){
    int discountRate;

    discountRate = basicRate - 10;
    // ... lots of code here 
    if ( isGoldCustomer ) {
        basicRate--;  // typo, we intended to say discountRate--, final catches this
    }
    // ... more code here

    return discountRate;
}

Solution 4

It doesn't make a lot of difference. It just means that you can't write:

stamp = null;
fTz = new ...;

but you can still write:

stamp.setXXX(...);
fTz.setXXX(...);

It's mainly a hint to the maintenance programmer that follows you that you aren't going to assign a new value to the parameter somewhere in the middle of your method where it isn't obvious and might therefore cause confusion.

Solution 5

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's considered sometimes a good coding practice.

Share:
66,539

Related videos on Youtube

John
Author by

John

Updated on June 06, 2020

Comments

  • John
    John almost 4 years

    What difference that final makes between the code below. Is there any advantage in declaring the arguments as final.

    public String changeTimezone( Timestamp stamp, Timezone fTz, Timezone toTz){  
        return ....
    }
    
    public String changeTimezone(final Timestamp stamp, final Timezone fTz, 
            final Timezone toTz){
        return ....
    }
    
    • Vishy
      Vishy over 13 years
      There are code analysers which warn if a parameter is re-used or reassigned. (Same for local variables) IMHO, This is a better way to catch such parameters if you find changing them is undesireable.
    • james.garriss
      james.garriss over 6 years
    • Sid
      Sid over 5 years
      I feel Java should make all input method arguments as final by default. And then if I want to modify the reference, I would have to do it manually. That way, guilt factor would prevent many such cases.
  • Donal Fellows
    Donal Fellows over 13 years
    +1: This is an important use case, and the only time when you need it. (The rest of the time it's just a matter of what's convenient for helping the programmer.)
  • Flo
    Flo almost 11 years
    That is not quite right. Even if the argument dateOfBirth is changed to another value in method2() this would have no effect on method2(), since Java passes by value and not by reference.
  • KodeWarrior
    KodeWarrior over 10 years
    May I ask the reasoning behind this ?
  • João dos Reis
    João dos Reis almost 10 years
    Might be better to use objects rather than primitives for this example, as primitive changes will always only be visible inside the method. And in the case of objects, you can still change them. You just can't point at a new object. In fact now I think about it, final doesn't really change anything compared to leaving it out, other than saving a variable declaration with AICs and having the compiler point out accidental modifications of parameters that you didn't want to modify for some reason.
  • Sam003
    Sam003 almost 9 years
    I have to add something: if parameters are primitive, I don't see any differences. Besides, if parameters are Collections(a list of objects...), adding final could not prevent them being modified.
  • Sid
    Sid almost 9 years
    Immutability is always a desirable trait. Java does not have it out of the box. Making variables final at least ensures reference integrity.
  • Sam003
    Sam003 almost 9 years
    I agree. But if we really want to achieve immutability for objects, we could try make a deep clone.
  • Amit Parashar
    Amit Parashar over 8 years
    No more necessary with Java 8.
  • simgineer
    simgineer over 6 years
    So with java 8 you can access from an inner class without it being final?
  • PeterMmm
    PeterMmm over 6 years
  • JoseHdez_2
    JoseHdez_2 over 5 years
    Great example of how declaring arguments as final can be useful. I'm partial to this but they're also a mouthful for 3+ parameters.
  • varun
    varun about 5 years
    @AmitParashar True, but Java 8 is just saving you from having to use the keyword "final" every time you have to use the variable in an inner class... The reality is that the compiler is merely making the finality implicit, you still need the variable to be effectively final... So, you still get a compile time error in case you try to assign to it later! Java 8: SNEAK 100 :)
  • Amit Parashar
    Amit Parashar about 5 years
    @varun agreed +1
  • mcy
    mcy over 2 years
    @KodeWarrior I know it is a little late, but the reasoning behind is the concept of closures.
  • Agustí Sánchez
    Agustí Sánchez over 2 years
    final does not help with immutability at all. The changes to primitive values are lost outside the method scope whether the parameter is marked as final or not. Changes to mutable objects are propagated outside the scope whether the parameter is marked as final or not. "Useless" is the word that comes to my mind.
  • Sid
    Sid over 2 years
    An immutable reference is the first step towards immutability.