Does pervasive use of final make sense?

R

Roedy Green

If that happened you would be needlessly blocked from reusing anyone's
code. You would have to go beg them to unlock the methods you needed.

Oops, I misread you. I thought you were calling for every method to
be final by default.

I tend to agree with you about parameters being final by default. I
was surprised when I first encountered them to discover they were not.

On the other hand it avoids the problem of inventing names for temps.

I think the rule comes from looking at the world from a JVM point of
view where parameters and local variables are the same sort of thing
-- something you index in the stack frame.
 
R

Roedy Green

For example,
it makes non-overridden methods and classes in your project final.

This is useful documentation. I often want to know when I am reading
code, does anyone override this method? and who? If I see "final" I
know NO.

However, you don't want to use final unless you mean "nobody does and
nobody SHOULD".

You need a scid for this sort of thing to keep the two uses separate.

see http://mindprod.com/scid.html
 
X

xarax

Roedy Green said:
I don't like the idea of final parameters because the finality of that
variable is PURELY the business of the implementation. Clients have no
concern with it. That information should not be exported to the
outside world.

Which is why I don't specify final parameters
on abstract method declarations (abstract class
or interface). Specifying final on a concrete method
parameter is the *only* way to get the intended
behavior of the compiler and really has nothing to
do with "exporting" that information to the outside
world. It can't possibly affect how the outside world
sees that method.

You reasoning, extrapolated to the N'th degree, would
mean that you would rather write this:

public void fubar()
{
synchronized(this)
{
/* do something useful */
}
}

instead of this:

public synchronized void fubar()
{
/* do something useful */
}

because placing "synchronized" on the method signature
unnecessarily broadcasts implementation details to the
outside world. That's simply not the case for synchronized
methods nor for final parameters. It's a peculiarity of
the language design and does not affect the outside world.
 
R

Roedy Green

Specifying final on a concrete method
parameter is the *only* way to get the intended
behavior of the compiler and really has nothing to
do with "exporting" that information to the outside
world. It can't possibly affect how the outside world
sees that method.

Human clients of your method see the word final in the declaration.
That should not be there. It does not concern them. It is just a
distraction.

If you change from final to unfinal clients should not have to
recompile. Final is not properly part of the method signature. It is
part of the implementation.

I am complaining here about sloppiness in the thinking of the language
designers, not making a clear line between what clients need to know
and what the implementation should keep to itself.
 
X

xarax

Roedy Green said:
Human clients of your method see the word final in the declaration.
That should not be there. It does not concern them. It is just a
distraction.

It's not in the declaration (interface or abstract class), just
in the definition (the concrete implementation of the method).
If you change from final to unfinal clients should not have to
recompile.

They don't have to recompile. A final parameter has ZERO
effect on callers of the method.
Final is not properly part of the method signature. It is
part of the implementation.

That's what I said. The same thing applies for "synchronized".
It has ZERO effect on the callers of the method.
I am complaining here about sloppiness in the thinking of the language
designers, not making a clear line between what clients need to know
and what the implementation should keep to itself.

That's what JavaDoc is for. The JavaDoc describes
the intended interface. I've never seen JavaDoc
include the "final" attribute for method parameters,
even though it's simple enough to determine that. Bottom
line is that "final" parameters do not affect clients in
any way.
 
T

Tony Morris

public void fubar()
{
synchronized(this)
{
/* do something useful */
}
}

instead of this:

public synchronized void fubar()
{
/* do something useful */
}

All arguments regarding encapsulation, etc. aside, the former is strongly
recommended against, since it causes a significant performance decrease.

--
Tony Morris
(BInfTech, Cert 3 I.T., SCJP[1.4], SCJD)
Software Engineer
IBM Australia - Tivoli Security Software
(2003 VTR1000F)
 
X

xarax

Tony Morris said:
All arguments regarding encapsulation, etc. aside, the former is strongly
recommended against, since it causes a significant performance decrease.

Chapter and verse please, from the JLS or JVM spec.
 
?

=?ISO-8859-1?Q?Daniel_Sj=F6blom?=

xarax said:
Chapter and verse please, from the JLS or JVM spec.

JVM spec 8.13, locks and synchronization. It doesn't say anything about
performance, but two points speak in favor of synchronized methods
instead of blocks:

Shorter code and simpler verification due to the lack of explicit
monitorenter/exit instructions.

Much simpler dataflow for compiler optimizations. Optimizing in
the presence of synchronized blocks and exception handlers is far harder
than it may seem.
 
T

Tony Morris

Chapter and verse please, from the JLS or JVM spec.

I remember reading a really good article that described why it is poor form
to use synchronized(this) (unless, of course, it is to provide additional
atomicity).
The article went into detail about the generated bytecode, and why
performance was degraded significantly.
I can't, for the life of me, relocate said article (I think it was a Sun
article).

There are other articles that mention the issue in a less detailed fashion.

--
Tony Morris
(BInfTech, Cert 3 I.T.)
Software Engineer
(2003 VTR1000F)
Sun Certified Programmer for the Java 2 Platform (1.4)
Sun Certified Developer for the Java 2 Platform
 
M

Mohun Biswas

Tony said:
I remember reading a really good article that described why it is poor form
to use synchronized(this) (unless, of course, it is to provide additional
atomicity).
The article went into detail about the generated bytecode, and why
performance was degraded significantly.
I can't, for the life of me, relocate said article (I think it was a Sun
article).

There are other articles that mention the issue in a less detailed fashion.

"The Java Programming Language", by Gosling/Arnold, 2nd Edition, has
some text regarding why synchronized methods are generally preferable to
synchronized(object). But I just looked and they don't discuss
performance; the issues are more around cleanliness and extensibility.
 
C

Chris Smith

Michael said:
Hi Timo,



Even with regard to methods, one needs a very good reason to use final.
One should mind, that final is ultimate.

Quite the opposite, actually.

If I make a method final, I can very easily change that method so as to
be non-final, and guarantee that I don't change the functionality of any
existing code.

If I make a method non-final, I can never undo that change unless I
*know* that I have access to all code that might interact with that
code.

As a result, methods should either be designed to be overridden (and
hence documentation should include an exact definition of under what
circumstances the method is called or *explicitly* leave that
undefined), or they should be declared final. Otherwise, you're just
bound to make some later change that breaks everyone else's code.

I don't do this, though. I think the real reason final is not used more
often is that it takes a level of thought and knowledge to realize that
it should be; and by that time, habits have formed.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
C

Chris Smith

Jean said:
I see one case where people do indeed often not use final and
I never understood why : in method parameters.

I asked some java guru at work why most people, including himself,
would simply not declare method parameters final and the answer
was actually very vague.

I see three reasons that I think are quite plausible:

1. The same as anything else; it requires a certain amount of
sophistication to realize that final is a good thing; and by that time,
habits have a hold.

2. As mentioned in this thread, it should be universal, which means your
code would be much longer for no good reason. You should just be able
to assume that parameters are not assigned, and have a tool check it for
you.

3. The one no one has mentioned:

This contradicts what was apparently the intent of the language designer
who added syntax for final parameters. Historically, prior to Java 1.1,
final method parameters were illegal (probably mainly for reason 2
above). They were added in conjunction with inner classes
*specifically* so that there would be a legal way for a local inner
class to access the value of a parameter.

Because of this, it has become conventional to use final on parameters
to indicate that they will be accessed by a local inner class in this
way. That's clearly not the meaning of the word "final", but it's
strongly associated by the language rule.

Hence, ironically, using the "final" keyword to really mean "final"
could be very misleading, and could lead someone to assume that you
intend to access a parameter from a local inner class, when that's
really not the case.

I think the reason I see it as a poor practice is a combination of all
three factors, with emphasis on 2 and 3.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 

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

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top