public final fields: a best practice?

2 views
Skip to first unread message

Moandji Ezana

unread,
Nov 20, 2009, 7:02:08 PM11/20/09
to java...@googlegroups.com
At his Devoxx talk, Dick casually mentioned that making final fields public was now a best practice. I do this sometimes on my non-work projects, but feel a little dirty. I doubt it would fly at work. 

I thought it was too trivial a point to bring up as a question after the talk, but what do you guys think? Is making final fields public acceptable?

Moandji

Christian Catchpole

unread,
Nov 20, 2009, 7:40:19 PM11/20/09
to The Java Posse
I don't know specifically what dick was talking about, but my concerns
are:

- does this give you dual methodologies for field access? members vs
getters

- a reference may be final (maybe immutable) now, but what do you do
if your class evolves to where the reference is now mutable?

- even though a field is final can the caller still modify the
object? I guess you can argue the same for any getter though.

Reinier Zwitserloot

unread,
Nov 20, 2009, 8:14:13 PM11/20/09
to The Java Posse
immutable is a heavily overloaded term. I would guess that dick is
referring to immutable references (final fields) pointing to immutable
objects.

I've done this myself, and later regretted it, as I wanted to
dynamically calculate a field lazily after a version rev, which wasn't
possible. All things being equal though, making a double immutable
public is not nearly as prohibitive to API revving as doing the same
to mutables.

On Nov 21, 1:40 am, Christian Catchpole <christ...@catchpole.net>
wrote:

bertvv

unread,
Nov 20, 2009, 10:03:10 PM11/20/09
to The Java Posse
Well, Dick was making the case of the functional programming style,
where immutable objects are the way to go. So a class should
definitely not evolve to a mutable version...

On Nov 21, 1:40 am, Christian Catchpole <christ...@catchpole.net>
wrote:

Dick Wall

unread,
Nov 23, 2009, 10:17:44 AM11/23/09
to The Java Posse
Perhaps the statement best practice was a little strong, or at least
taken out of context.

I was aiming towards the idea that for value transfer objects -
effectively structs from C/C++, public finals are a perfectly
acceptable option and in my opinion preferable to getters for the same
purpose. For these kind of immutable value objects, they introduce
less chance that you will get anything but the immutable values for
those fields, the principle of least surprise. On top of that, you
save a bunch of boilerplate as well.

Since the references are final, there seems little to be gained by
making them private and restricting access through getters unless you
want to somehow add behavior to the accessor methods - and if you do
that you probably aren't wanting value objects in the first place.

Of course, as mentioned, this idea definitely works out best with
final references to immutable objects, but will behave the same as
getters even if the objects referenced are not immutable - you still
end up with the same references from the direct access or from the
getter, what you do with it after that is your choice.

Scala has uniform access for properties, so that eliminates the
distinction (getXXX methods are only generated when you need
compatibility with JavaBeans for some reason). For everything else
though, I would still claim that final publics are a good idea when
all you want is a "struct".

Cheers

Dick

Reinier Zwitserloot

unread,
Nov 23, 2009, 3:30:23 PM11/23/09
to The Java Posse
Well, that, or @Data :P

hlovatt

unread,
Nov 24, 2009, 3:23:09 AM11/24/09
to The Java Posse
The problem I have had is that I did originally want a struct of a
certain structure, but then I changed my mind. For example I once made
a Complex type this way with real and imaginary final fields, problem
was I latter found that I was always multiplying and not adding the
complex numbers. Then I wished I had magnitude and phase fields (which
make multiplication easy). If I had used getters and setters I could
have changed.

The thing that appeals about final fields is the short syntax both for
writing the class and for accessing the fields, Scala style uniform
access and case classes anyone.

NB

1. Scala case classes aren't exactly what I would want since they
expose the final fields, it would be better if the case classes only
exposed the getters.

2. I can hear someone from the posse screaming properties in the
background :)

On Nov 23, 4:17 pm, Dick Wall <dickw...@gmail.com> wrote:

Jess Holle

unread,
Nov 24, 2009, 5:43:00 AM11/24/09
to java...@googlegroups.com
hlovatt wrote:
> The problem I have had is that I did originally want a struct of a
> certain structure, but then I changed my mind. For example I once made
> a Complex type this way with real and imaginary final fields, problem
> was I latter found that I was always multiplying and not adding the
> complex numbers. Then I wished I had magnitude and phase fields (which
> make multiplication easy). If I had used getters and setters I could
> have changed.
>
> The thing that appeals about final fields is the short syntax both for
> writing the class and for accessing the fields, Scala style uniform
> access and case classes anyone.
>
> NB
>
> 1. Scala case classes aren't exactly what I would want since they
> expose the final fields, it would be better if the case classes only
> exposed the getters.
>
> 2. I can hear someone from the posse screaming properties in the
> background :)
>
I can see where adding -> field/property dereferencing (no, "." will not
work well here as foo.bar would radically change meaning from what it
means today where one has access to the "bar" field) would be a nice
solution here. With the right load time semantics built into the JVM,
one could presumably figure out the right access approach once (field or
get method) and use it from thereon without further lookup overhead.

That aspect of the nebulous properties stuff (nebulous = oh, I meant
events too and automatic event listeners and....) seems reasonably
straightforward and helpful to add.

In the mean time I use public final fields for "localized" value
classes, i.e. those used in a fairly small scope. If the class is used
broadly I tend towards getters and private fields to reduce the
potential need for refactoring later.

--
Jess Holle

Kevin Wright

unread,
Nov 24, 2009, 6:18:18 AM11/24/09
to The Java Posse

Scala case classes *are* exposing methods, it's just that the getter
for 'x' is named 'x' and the field is kept very well hidden... If you
want javabean-style properties then you can use the @BeanProperty or
@BeanInfo annotations

And why should it matter if foo.bar is a field or a method, so long as
the method is free from side-effects?
Of course, there may be performance considerations for calculated
members, but this smells far too much like premature optimization to
me.

By keeping names uniform, it becomes possible to change your mind at a
later point and not have to refactor the users of your class.
> Jess Holle- Hide quoted text -
>
> - Show quoted text -

Jess Holle

unread,
Nov 24, 2009, 6:30:42 AM11/24/09
to java...@googlegroups.com
Kevin Wright wrote:
> Scala case classes *are* exposing methods, it's just that the getter
> for 'x' is named 'x' and the field is kept very well hidden... If you
> want javabean-style properties then you can use the @BeanProperty or
> @BeanInfo annotations
>
> And why should it matter if foo.bar is a field or a method, so long as
> the method is free from side-effects?
>
It only matters to the mountains of existing Java code in cases where
the method is not free from side effects, which are numerous. If all
usages of foo.bar suddenly started means foo.getBar() [assuming there is
a getBar()] in Java lots of code would break. Worse, more code would
mean something subtly different such that a change to getBar() to have
side-effects would do something completely different in Java versions
prior to such a change and after.

It does not matter at all to a new language forming new rules.

--
Jess Holle

Kevin Wright

unread,
Nov 24, 2009, 6:45:39 AM11/24/09
to The Java Posse

Other than maybe a log statement or cache lookup, I think that I'd
condone flogging for anyone who wrote a getBar() method with side
effects :)

Even a permissions check would have to be very well argued, as it can
behave differently based on the context.

The problem is that getBar() with side-effects *already* breaks
expected behaviour.

Jess Holle

unread,
Nov 24, 2009, 7:34:13 AM11/24/09
to java...@googlegroups.com
It is not at all unusual for getBar() to have subtle differences from being simply "return bar;"  These are not necessarily what one would consider "side effects", but there's often a reason for getBar() to exist and do something more than "return bar;".  For instance, bar might be of the same type as getBar(), but getBar() might do some sort of cleansing of bar for external use.  bar might be a collection and getBar() might well return a copy or a non-modifiable wrapper around bar.  In any of these cases, having code suddenly switch in meaning from foo.bar to foo.getBar() could be disastrous to the code's behavior.

Which is why I believe uniform access is fine and (quite) good, but must use "->" not "." lest it wreak havoc on existing code and produce subtly but nastily different meanings from the same Java code compiled with / without the uniform "."-based access.

If "." had meant uniform access for the last decade of Java's lifespan, that would be fine.  At this point trying to introduce this would cause a royal mess.

--
Jess Holle

Kevin Wright wrote:
--

You received this message because you are subscribed to the Google Groups "The Java Posse" group.
To post to this group, send email to java...@googlegroups.com.
To unsubscribe from this group, send email to javaposse+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/javaposse?hl=en.



  

Reply all
Reply to author
Forward
0 new messages