简体   繁体   中英

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 (ie 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 .

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.

If you are ever going to access this value from JSF Page, it will expect getFoo rather than just foo (even if you write object.foo ).

Apart from that- today this field is final, long time from now it can change (I guess). Even if the chance is very close to 0, I believe that there is no overkill in following good practices. Vast majority of the time you are making changes than writing code from scratch, so it is much better to safeguard yourself whenever possible (if all it takes is writing private and in case of eclipse about 4 clicks to generate the getter and setter automaticaly).

To extend Feldgendler's answer (with information which may be useful for someone needing the answer of this question --- I believe this is relevant because it is really a question about encapsulation):

In effect of using private modifiers you will have to create the "getter" (eg int getX(){ ... } ) to sustain access. Which can be declared in an implemented interface . A Java interface does not allow declaration of instance variables, such as the example of final int x; --- or of any other variable lacking the static modifier. The interface will act as a declaration of the behavior any implementing class will have.

If implemented like:

Coordinate implements ICoordinate { ... }

it could be useful in many scenarios:

The use of an interface

  • Self-documentation of an API.
    • Easy to read, document and manage.
    • Hence, allowing several implementations to be readily used and swapped.
    • In component-based design and more: provide explicit means to provide or require described behavior without actually having any implementation code ready.
      • Example: One could then create a database component that provides an interface. John Doe wants to write a program that will in the future use a database. For now however it is sufficient to use some other simpler form of storage. In order not to re-code what is already working code when the day comes John could implement an interface (maybe given the name interface IDatabase ) with the methods void insert( ... ); Object get( ... ); void insert( ... ); Object get( ... ); and perhaps a few more -- then implement his temporary solution. The day comes and he now has a database implementing the same interface IDatabase . To swap to the new database he might only need to change *one line of code* (eg the constructor call)!
  • An example for the sake of it: http://pastebin.com/vvV2Nck8

Using private modifier

  • It Clarifies the intent of the class! Much like the interface, it has the nature of being self-documenting. (It has no value in security)
    • private modifier would imply that it is NOT to be accessed out of scope. Or equivalently -- only to be accessed within a certain scope. Same of course applies to public , "package-private" (no modifier implies package-private) and protected .
    • Accessing an attribute will not explicitly tell the caller what kind of variable it is. Having a getter but no setter says something else however...
    • NOTE: For constants (eg static final double LIGHT_SPEED ) there is reasonable reason to omit a getter and have it public instead. This being just convention as it will be clear to what is a constant and what is an object with its own members.
    • NOTE2: Read about final keyword and its impact on optimization if interested. They can be used in methods as well as attributes. ( Does use of final keyword in Java improve the performance? is an example)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM