aspose file tools*
The moose likes Java in General and the fly likes final in method argument Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "final in method argument" Watch "final in method argument" New topic
Author

final in method argument

Olexiy Prokhorenko
Ranch Hand

Joined: Jul 11, 2004
Posts: 97
Can anybody give me a clear explanation when it is the best way to use 'final' in method arguments? Really, cannot get it. Primitives are passed by value, objects are passed by reference to method. Even if we will use 'final' with object in method argument, all changes to object inside the method are possible and will affect real object.

So, what for? I feel myself very newbie, but cannot find any answer.


<a href="http://www.BossTalks.com" target="_blank" rel="nofollow">http://www.BossTalks.com</a><br />Free advices and help for entrepreneurs: from Idea to IPO<br />Software and IT Project Management forum
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
I think the main reasons to do it is that (a) there's no good reason to want to change the value of a paramenter, and (b) if you do change the value of a parameter, chances are good that it was unintnetional, and you probably meant to do somethign else. So making all parameters final is a way of facilitating error detection. Probably the most common case is if you (intentionally or accidentally) declare a local variable whose name matches an instance or class variable. Many of us do this intentionally for setter, and it usually works fine since setters are very short and we always use the same formula:

It's hard to get that wrong. But if the method were longer, and it ended with something like

then chances are good that we really meant to say this.foo rather than foo. But we screwed up, and the compiler has no reason to complain. On the other hand if you declare the parameter foo as final, the compiler would complain as soon as you accidentally try to assign it a new value.

Now personally, I don't usually do this, because I don't like the way it forces all method declarations to be notably longer, and because I have to explain why I'm doing it to every new person that comes along. The minor benefit I get from the addedd error detection hasn't been enough to fully sway me, yet. However I wouldn't object at all if this technique became much more common. And I'd really like it if a language simply made all method parameters implicitly final. That doesn't change how I code today, but it's something I'd like to see.


"I'm not back." - Bill Harding, Twister
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
Originally posted by Olexiy Prokhorenko:
Can anybody give me a clear explanation when it is the best way to use 'final' in method arguments? Really, cannot get it. Primitives are passed by value, objects are passed by reference to method. Even if we will use 'final' with object in method argument, all changes to object inside the method are possible and will affect real object.

So, what for? I feel myself very newbie, but cannot find any answer.


All types are passed by value. Objects are never passed. Objects are not types. Now that we've established a correct premise, let's look at why method arguments might be declared final. A good way to look at this is to figure out why method arguments might *not* be declared final. The single biggest reason is "it takes an extra 5 keystrokes in a standard text editor".

In most contexts (in practice), local declarations (including method parameters) should be final, but are not simply because of implicit "non-finalness". One day, a language might exist where local declarations are implicitly final and explicitly not final with an additional keyword (such as "var"). The only time where I've ever not declared a method parameter final is for the use of recursion, which is contrived anyway - it was an academic exercise.


Tony Morris
Java Q&A (FAQ, Trivia)
Jeff Albertson
Ranch Hand

Joined: Sep 16, 2005
Posts: 1780
I am susprised that no one has mentioned the following need for a local final. It's the only reason I even make a parmater final:
Without the final modifier, you will get the syntax error:

local variable f is accessed from within inner class; needs to be declared final


There is no emoticon for what I am feeling!
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078
Anonymous classes that need to use a parameter as Jeff demonstrated is the most common case for a 'need' that I come across. Other than that I almost never use it. I suppose it might be a good practice to declare anything you don't intend on having altered as final. I don't see any disadvantages to declaring them final but I can see a few advantages.
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
Originally posted by Ken Blair:
Anonymous classes that need to use a parameter as Jeff demonstrated is the most common case for a 'need' that I come across. Other than that I almost never use it. I suppose it might be a good practice to declare anything you don't intend on having altered as final. I don't see any disadvantages to declaring them final but I can see a few advantages.


Better still, have your build fail if you declare any local (or field) that is "write once" (also fail for a "write never" (unused) local). At least, I do and the benefits are very apparant.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Regarding using final for variables used in local and anonymous classes, I omitted that simply because in those cases where you need to do it, it's obvious because the compiler will tell you so directly. I was more interested in the less obvious benefits of using final in general. Still, use in anonymous classes did deserve mention, so thanks to Jeff for bringing it up.

[Tony]: Better still, have your build fail if you declare any local (or field) that is "write once"

What's wrong with "write once"? Do you mean, fail for any write-once field which is not declared final? (I'd agree with that.)

Also, I'm curious about the time you found it necessary (or at least useful) to not declare a parameter final - even if it was a contrived case. I'd have thought method params could always be final. Was there perhaps an observable performance difference? Some other reason? Any further details you recall would be appreciated.
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
Originally posted by Jim Yingst:
Regarding using final for variables used in local and anonymous classes, I omitted that simply because in those cases where you need to do it, it's obvious because the compiler will tell you so directly. I was more interested in the less obvious benefits of using final in general. Still, use in anonymous classes did deserve mention, so thanks to Jeff for bringing it up.

[Tony]: Better still, have your build fail if you declare any local (or field) that is "write once"

What's wrong with "write once"? Do you mean, fail for any write-once field which is not declared final? (I'd agree with that.)

Also, I'm curious about the time you found it necessary (or at least useful) to not declare a parameter final - even if it was a contrived case. I'd have thought method params could always be final. Was there perhaps an observable performance difference? Some other reason? Any further details you recall would be appreciated.


Yes I did mean that (fail for a "write once" that is not declared final).
I vaguely recall the "need" to declare a method parameter non-final for some very common academic exercise (I lecture part-time at a university) where recursion was used. I'll try to find it or recall it in my head.
Olexiy Prokhorenko
Ranch Hand

Joined: Jul 11, 2004
Posts: 97
Thanks everybody for your opinions!

Yes, I am not even talking about marking final for inner classes. That's just certain thing.
In general, I understand that it's better to show that some argument is not intended to be changed inside the method scope, but from other point view -- I believe it's a bad practice to change method argument inside method at all. :-)
But marking it method argument's as final does not prevent it to be changed.
Jeff Albertson
Ranch Hand

Joined: Sep 16, 2005
Posts: 1780
I'll admit it. I've written code that looks like this.
I know there are web sites where you can go and confess to past misbehaviours.
But is there any devoted to coding peccadillos? I mean, outside of Microsoft forums
Alan Moore
Ranch Hand

Joined: May 06, 2004
Posts: 262
Everybody has been using primitives in their examples, but object references are a different story. If the object is mutable, declaring it final doesn't stop you from changing its state; it only stops you from assigning the variable to a different object. For example, say you're passing a StringBuffer into a method so you can append some text to it. Declaring the parameter final doesn't stop you from doing that, but it prevents your accidentally reassigning the variable to a different StringBuffer and creating a hard-to-find bug.

I agree that all parameters should be implicitly final. I don't make them final because (1) I'm lazy, (2) lines tend to be too long already, and (3) dammit, I shouldn't have to!
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
Originally posted by Alan Moore:
Everybody has been using primitives in their examples, but object references are a different story. If the object is mutable, declaring it final doesn't stop you from changing its state; it only stops you from assigning the variable to a different object. For example, say you're passing a StringBuffer into a method so you can append some text to it. Declaring the parameter final doesn't stop you from doing that, but it prevents your accidentally reassigning the variable to a different StringBuffer and creating a hard-to-find bug.

I agree that all parameters should be implicitly final. I don't make them final because (1) I'm lazy, (2) lines tend to be too long already, and (3) dammit, I shouldn't have to!


Object references are not a different story in the context of the conversation; they just imply "dereference" semantics, which means you can mutate the underlying instance if such an operation is exposed. That has nothing at all to do with the final modifier. Specifically, object references are a "different story" just as much as typewriters or hippopotamuses or <insert-random-topic-here/> are.
 
 
subject: final in method argument