Search code examples
javaabstractfinal

Why use private modifier for immutable final instance var?


I'm writing a Java class representing some simple geometry.

At the top-most abstract class (which itself is package-private) I have declared attributes that I need be accessed from subclasses in the same package.

If I declare an attribute as final in the AbstractClass,

final int foo;

I'll able to access it in the package directly, without any fuss of a getter method. However. Doing according to "praxis" (or what I believe is the common style) would be:

private final int foo;

which would of course require a non-private getter. The subclasses would have to refer to foo (which is a very relevant and quintessential attribute) as if it were some external object:

this.getFoo();

It adds code and removes the direct way of accessing these members (i.e foo).

Are there any disadvantages of skipping the private modifier, since they're anyway final and I'm not worried of exposing these attributes internally in the package?

I'm aware of OO-advocates claiming that getters/setters is a very natural way for objects to access their own attributes - but when does this make any non-cosmetic, non-[insert any JavaBeans-style thing], difference?

Consider an inner class, Coordinate, which is so simple because it has two int attributes - leaving all usage for class OuterClass:

class OuterClass{
    final static class Coordinate{
        final int x, y;
        Coordinate(int x, int y){
            this.x = x;
            this.y = y;
        }
    }
    Coordinate coordinate;
}

For this inner class - why would I bother with the praxis of creating a getter? A getter would introduce more code and force any class in the same package to call coordinate.getX(); instead of simply coordinate.x;. Any overhead here? Notice the final modifier on the class Coordinate.


Solution

  • The advantage of getters is decoupling interface from implementation. Today your getFoo might do nothing but return foo, but in the future you might want, for example, to remote the foo member and return a computed result instead. A getter will allow you to do that without requiring a change at each call site.