effects of "final" in parameters

T

tom fredriksen

Hei

Just a quick question.

ex.
testFunc(final String elems)

- how often is "final" actually used in code to make parameters
immutable?
- does using final have an optimisation effect on run-time, both as a
parameter and as a regular variable?
i know it is stated that this can lead to an optimisation, but does
the compiler or jvm utilise it in real life? if so, does anybody
have any idea of how much effect it does have.

/tom
 
C

Chris Uppal

tom said:
- how often is "final" actually used in code to make parameters
immutable?

Note that it doesn't make the referred-to object immutable, it just means that
you can't assign another object ref to the parameter variable.

Some people seem to use it a lot. I consider it pointless myself. (Unless, of
course, I /have/ to use it to satisfy the compiler that an inner class won't
break if it refers to the parameter). If I don't want to change the value of a
parameter then I don't change it -- adding decoration to tell the compiler that
I don't intend to change it, so that it can then check that I don't change it,
seems a singularly unproductive exercise.

- does using final have an optimisation effect on run-time, both as a
parameter and as a regular variable?
i know it is stated that this can lead to an optimisation, but does
the compiler or jvm utilise it in real life?

No. The final attribute of a local variable or parameter is not reflected in
the classfile, so there is no way that it can possibly have any effect at
runtime.

Final /fields/ are different, as are final methods -- and it's the latter that
are sometimes touted as an optimisation (which I doubt, but have never tried to
measure).

-- chris
 
V

VisionSet

tom fredriksen said:
Hei

Just a quick question.

ex.
testFunc(final String elems)

- how often is "final" actually used in code to make parameters
immutable?

I use it more and more.
It results is more elegant code, if you hold on to references and mutate the
object rather than providing a new one.
a) Often it leads to poorer performance to constantly reinstantiate.
b) You can provide a reference once and then forget about it, it'll always
have that object, final means you can't inadvertently point it elsewhere.
It means you can produce a better design without uneccessary associations
that are there to maintain the reference.
c) it is self documenting code - always a good thing.

Of course as Chris has pointed out, it doesn't do anything magical, but it
is a great compiler flag that keeps your code on track with your intent.
That plus the optimisation which I have no hard and fast info on.
 
T

Thomas Hawtin

Chris said:
Final /fields/ are different, as are final methods -- and it's the latter that
are sometimes touted as an optimisation (which I doubt, but have never tried to
measure).

Years ago making a method used in an inner loop final could improve
performance significantly. I found it useful for one get method once,
and then removed the field. However, this century JVMs will inline
methods anyway and it makes no difference.

Final fields may have some impact on performance from Java 1.5. They
need not be reread, even when dealing with synchronised blocks and
reading volatiles. I haven't tested to see whether that actually makes
any difference. If you have a field that could be made final, it should
be made final regardless of performance concerns.

Tom Hawtin
 
A

Andrew McDonagh

Chris said:
tom fredriksen wrote:




Note that it doesn't make the referred-to object immutable, it just means that
you can't assign another object ref to the parameter variable.

Some people seem to use it a lot. I consider it pointless myself. (Unless, of
course, I /have/ to use it to satisfy the compiler that an inner class won't
break if it refers to the parameter). If I don't want to change the value of a
parameter then I don't change it -- adding decoration to tell the compiler that
I don't intend to change it, so that it can then check that I don't change it,
seems a singularly unproductive exercise.

The voice of reason - thank you Chris!

The amount of times I've tried explaining this to others...... (walks
away shaking his head...)
 
A

Adam Maass

Chris Uppal said:
Note that it doesn't make the referred-to object immutable, it just means
that
you can't assign another object ref to the parameter variable.

Some people seem to use it a lot. I consider it pointless myself.
(Unless, of
course, I /have/ to use it to satisfy the compiler that an inner class
won't
break if it refers to the parameter). If I don't want to change the value
of a
parameter then I don't change it -- adding decoration to tell the compiler
that
I don't intend to change it, so that it can then check that I don't change
it,
seems a singularly unproductive exercise.

Some commentators have suggested making all formal parameters 'final' as a
default. Reaons:

1. Most methods will not assign to their formal parameters. Adding the
'final' keyword to them makes the compiler check that they don't.

2. It is sometimes syntactically necessary -- for use in anonymous classes.

3. Because you can't assign to the formal parameters, you can't expect that
the actual parameters will be changed.



Of course, IMHO, these points are all pretty silly. And I haven't actually
seen this recommendation put into widespread use.


-- Adam Maass
 
R

robson

Most Java code analyzers (Checkstyle, PMD) I have used have special
rule that checks if all method parameters are defined as final. By
default this rule is usually enabled - to enforce good programming
practice. Very often your code is maintained and developed by other
programmers, it is good idea to mark, that you don't want to assign any
value to method parameter variables.
 
T

Timbo

Chris said:
tom fredriksen wrote:




Note that it doesn't make the referred-to object immutable, it just means that
you can't assign another object ref to the parameter variable.

Some people seem to use it a lot. I consider it pointless myself. (Unless, of
course, I /have/ to use it to satisfy the compiler that an inner class won't
break if it refers to the parameter). If I don't want to change the value of a
parameter then I don't change it -- adding decoration to tell the compiler that
I don't intend to change it, so that it can then check that I don't change it,
seems a singularly unproductive exercise.
But you can then say the same for static type analysis: if one
doesn't want to assign a value of a particular type to a variable,
then don't do it.

I realise that this is not as straightforward as ensuring you
don't assign to a reference, but I wouldn't say it is pointless,
because you get it for free. It's certainly not counter-productive
or harmful. I don't think I ever change the value of a reference
that is passed to a method (I can't think of a good reason to), so
it makes sense that I should use it to document (and check)
this... although I don't :)
 
D

Daniel Dyer

Most Java code analyzers (Checkstyle, PMD) I have used have special
rule that checks if all method parameters are defined as final. By
default this rule is usually enabled - to enforce good programming
practice. Very often your code is maintained and developed by other
programmers, it is good idea to mark, that you don't want to assign any
value to method parameter variables.

There's nothing wrong with that approach, but I don't think it is
necessary. It assumes that there are situations in which you would want
to re-assign method parameters. But since Java is pass-by-value, there is
no useful reason to reassign method parameters. I leave them non-final
and assume that they never change (yes, I know about assumption being the
mother of all ****-ups).

When it comes to fields, I'm a final Nazi. Everything is final unless
there is a good reason for it not to be. I guess this is inconsistent
with my preference for non-final method parameters, but in the case of
fields there are uses for both final and non-final so don't make any
assumptions.

Dan.
 
C

Chris Uppal

robson said:
Most Java code analyzers (Checkstyle, PMD) I have used have special
rule that checks if all method parameters are defined as final. By
default this rule is usually enabled

Madness !

-- chris
 
E

Eric Sosman

robson wrote On 03/01/06 08:38,:
Most Java code analyzers (Checkstyle, PMD) I have used have special
rule that checks if all method parameters are defined as final. By
default this rule is usually enabled - to enforce good programming
practice. Very often your code is maintained and developed by other
programmers, it is good idea to mark, that you don't want to assign any
value to method parameter variables.

Why does "good programming practice" forbid or even
discourage assigning new values to method arguments? It
seems a silly restriction to me, one that has little
purpose except to introduce unneeded local variables to
hold copies of the arguments. For example,

void doSomething(SomeType thing) {
if (thing == null)
thing = DEFAULT_THING;
...
}

would become something like

void doSomething(final SomeType thing) {
SomeType realThing = (thing == null)
? DEFAULT_THING : thing;
...
}

or even

void doSomething(final SomeType thing) {
final SomeType realThing = (thing == null)
? DEFAULT_THING : thing;
...
}

As far as I can see, this has no effect other than to
force the reader of the code to comprehend an extra
variable. Why increase the cognitive burden?
 
C

Chris Uppal

Timbo wrote:

[me:]
But you can then say the same for static type analysis: if one
doesn't want to assign a value of a particular type to a variable,
then don't do it.

Certainly you can -- and I often do. I'm no fan of declarative static typing.

However these cases are not really parallel -- there're the little matters of
scale and correctness to consider too.

First off, the only reason why I might decide that I "don't want" to assign to
a parameter is because I don't /in fact/ assign to it. There is no good reason
to avoid doing so, it's just that -- as the code happens to turn out -- there
may be no need to. So if I "decide" I don't want to assign to a parameter, but
nevertheless do so, then it was my "decision" that was wrong, not the
assignment. So what value does the 'final' qualifier give ? What error does
it prevent ? None at all.

Secondly, about scale, you may say (I suspect this is in some people's minds; I
don't mean "you" personally) that by declaring it 'static' I make it plain that
I don't actually assign to it. That is a very good reason to make instance
fields (or other fields) final -- a very good reason indeed. But it doesn't
apply to method parameters. If your code (routinely) has methods that
are too long, or too convoluted, for you to be able to /see/ what use is made
of a parameter (or any other variable), then you have problems that are a great
deal more serious than just the missing 'final' qualifiers.

-- chris
 
R

robson

Sorry guys, I made mistake about Checkstyle rules, they are not as
restrictive as I wrote. There are rules which advice that NON-MODIFIED
variables / parameters (there were no assignment in code after
declaration) COULD be declared as final - but not that "ALL variables /
parameters should be final".

There is also one rule called "Parameter Assignment", it is documented
as follows:

"Disallow assignment of parameters.
Rationale: Parameter assignment is often considered poor programming
practice. Forcing developers to declare parameters as final is often
onerous. Having a check ensure that parameters are never assigned would
give the best of both worlds."
- fits pretty well to this discussion ;)

Also in PMD there is rule:

"AssignmentInOperand: Avoid assigments in operands; this can make code
more complicated and harder to read."

- but it is placed in "Controversial Rules" group :))

Just to sum up: there is no simple answer, or "The Truth is Out
There..."
 
R

robson

Mistake again, I gave wrong PMD rule, the good one is:

AvoidReassigningParameters: Reassigning values to parameters is a
questionable practice. Use a temporary local variable instead.

- this should answer your question Eric - yes, according to Java gurus
it is better to introduce local variable and assing value to it.
 
T

Thomas Weidenfeller

robson said:
Most Java code analyzers (Checkstyle, PMD) I have used have special
rule that checks if all method parameters are defined as final. By
default this rule is usually enabled - to enforce good programming
practice.

Only that it is not good programming practice. final buys you almost
nothing, it is just a waste of perfectly good electrons in that context.
I regard throwing heaps of final into Java method parameters as bad,
not good practice.

Just because someone thinks intentionally assigning a new value to a
parameter variable is a bad programming practice doesn't mean it is.
Variables in Java are there to be assigned. Java is not a
single-assignment only language (I can recommend such a language if you
want one). Destructive assignments are a natural part of Java. Why
should it suddenly be bad practice to use that natural part of the language?

/Thomas
 
R

Roedy Green

Very often your code is maintained and developed by other
programmers, it is good idea to mark, that you don't want to assign any
value to method parameter variables.

why? What advantage is there is the overhead and confusion of a
second variable? you are just likely to introduce bugs that way.
 
D

Dimitri Maziuk

Chris Uppal sez:
Madness !

Not really, just a logical evolution of Java philosophy. We begin
with programmers incapable of freeing heap space they used and
naturally progress to programmers incapable of remembering they've
modified method parameter two lines ago.

Dima
 
J

James McGill

why? What advantage is there is the overhead and confusion of a
second variable? you are just likely to introduce bugs that way.

A variable is overhead, yes, but does not necessarily add confusion.

If you're likely to introduce bugs just because you've added a variable,
you really need to practice.
 
J

James McGill

- this should answer your question Eric - yes, according to Java
gurus
it is better to introduce local variable and assing value to it.

It's already clear that some believe this, but what is the rationale for
it? Does the idea come from someone's criteria for symmetry in design,
or is there some argument that holds all the way down to the bytecode?

It's one thing for a manager or professor to say how they'd like things
to be coded, and it's entirely another thing to justify the idea to the
satisfaction of a disinterested party.

Merely saying something is a "questionable practice" makes it
questionable, by tautology, but it doesn't give anyone else a basis on
which to question it, and it certainly doesn't go anywhere near
*answering* the question -- which is what we really want. Question the
practice, find the answer, and then instead of a "questionable practice"
we will have a pragma or a praxis, depending on the answer...

Even if the answer is one thing for a performance idiom and another
thing for a design idiom, the problem could still be stated much more
clearly.
 
C

Chris Uppal

James said:
If you're likely to introduce bugs just because you've added a variable,
you really need to practice.

If you have two variables that consistently /might/ hold the same information,
then that is a classic way of introducing bugs. If there were some way of
pushing the old variable out-of-scope when you assign to the new one, then
there would be no (potential) problem. Not clear at all what that buys you
over just assigning to the parameter though.

I should admit that the potential for confusion, even with two aliases for the
same data, would be pretty low if the code were written well in the first
place.

-- chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,432
Messages
2,571,682
Members
48,796
Latest member
Greg L.

Latest Threads

Top