Domanda

Ok, so I understand why we should declare an argument to be final from this question, but I don't understand why we shouldn't...

Since Java always uses pass by value, this means that we can't return a new value through the given argument, we can only overwrite it, and make the argument useless therefore, because we don't use the passed value...

Is the only benefit of non-final method arguments in Java the fact that you don't have to make a local variable of the arguments' type?

P.S. This question was triggered by PMD's rule of MethodArgumentCouldBeFinal

È stato utile?

Soluzione

I can think of only 2 reasons not to make a parameter final:

  1. to save the use of a local variable if you need to overwrite the parameter's value in some edge cases (for instance to put a default if the param is null etc.). However, I wouldn't consider that a good practice in general.

  2. to save 6 characters per parameter, which improves readability.

Reason 2 is what leads me not to write it most of the time. If you assume that people follow the practice of never assigning a new value to a parameter, you can consider all parameters as implicitly final. Of course, the compiler won't prevent you from assigning a parameter, but I can live with that, given the gain in readability.

Altri suggerimenti

It prevents you from making unintentional error in your code. Rule of thumb here is to make each field and each function argument you know you shouldn't change (I mean reference, you still can change value) in your code as final.

So basically its a mean to prevent programmer from shooting their foot. Nothing more.

Whether you've to declare a local variable final or not (method parameter comes under this), is more of the requirement than a convention. You'll not get a certain answer saying you should always use final or you should never use final. Because that is really a personal preference.

I personally mark the parameters or local variables final when I really don't want their values to be changed, and it even shows my intention to other developers not to overwrite the values. But I don't do it for every parameters. Also for some, using final seems to be noise, as that really increases the code base.

Rule of thumb: Don't use it.

Final cannot stop you changing objects, only its reference, and this is because objects in java are, usually, not inmutable.

Take a look to this code:

class Example{
 // think about this class as a simple wrapper, a facade or an adapter
 SomeClass inner = new SomeClass();
 setInnet(Someclass inner){
   this.inner = inner;
 }
 // delegate methods.....
}

Now, in a method:

private void (final Example examp){

....

examp will be always the same object, but inner can vary... And inner is the important object here, the one which makes everything!

This may be an extreme example, and you may think that inner could be final but, if it's a utillery class, maybe it shouldn't. Also it's easy to find a more common example:

public void (final Map map){;
....
//funny things
....
//and then, in a line, someone does:
map.clear()
// no we have the same reference... but the object has change...
....

So, my point against final in arguments is that it's not guaranteed that all the code inside a final class is inmutable and so the final word can end lying you and mascarading a bug...

By putting final in params you can only show wishes, not facts, and for that you should use comments, not code. Moreover: it's a standar (de facto) in java that all arguments are only input arguments (99% of the code). Thus, final word in params is NOISE because it exists and means nothing.

And I don't like noise. So I try to avoid it.

I only use final word to mark the inner variables that will be used in an anonymous inner class (you can avoid marking it if they are effectively final, but it's cleaner and more readable).

UPDATED

final means 'assigned once' which in applied to method arguments means nothing in a program's logic nor in its design.

You can assign the arguments to a new object inside a method and outside there will not be any change.

The only difference putting final in arguments will be that you will not be able to assign that entities to another objects. Assigning arguments is something which may be ugly and something to avoid but its only a style problem and, at that point, the style problem should be the assignation itself and not the ausence of 'final' word.

I think that final is useless in arguments (and so, noise), but if someone is able to find a use of it I'll be happy to learn it. What can I achieve putting 'final' that cannot achieve without putting it?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top