///Java Accessor Visibility

Java Accessor Visibility

When to make accessors public, and when to keep them private

This article gives guidance on the visibility of accessor methods. It is modified from Chapter 8 of The Object Primer 2nd Edition.

We introduced accessors in "Accessors increase robustness of Java code" where we saw that accessors (member functions that directly manipulate the value of fields) may add minimal overhead to your code. At the same time, accessors increase the robustness of classes and components because they help to hide the implementation details of your classes. Accessors come in two flavors: setters and getters. A setter modifies the value of a field; a getter obtains its value.

Your choice of visibility for a member function, which defines the level of access to it by Java objects, provides an opportunity to reduce the coupling within your software. Because accessors are simply Java member functions, it is therefore important that you choose the visibility of your accessors wisely. You saw in "Member function visibility in Java programs" that Java offers four levels of visibility: public, protected, private, and default.

  • A member function with public visibility can be invoked by any other member function in any other object or class.
  • A member function with protected visibility can be invoked by any member function in the class in which it is defined or any subclasses of that class.
  • A member function with private visibility can only be invoked by other member functions in the class in which it is defined, but not in the subclasses.
  • A member function with default visibility is effectively public to all other classes within the same package, but private to classes external to the package. This is sometimes called package visibility or friendly visibility.

So how do you determine the proper visibility of an accessor method? My experience is that you should always strive to make accessors protected, so only subclasses can access the attributes. You should try to make accessors private if subclasses don’t need access to the attribute. Only when an external class or object needs to access an attribute should you make the appropriate getter or setter public. It is quite common for the visibility of corresponding getter and setter methods to be different: in the class Seminar, you see the getTitle() method has public visibility, yet setTitle() has private visibility. As Figure 1 reveals, the only place the setter method is called is in the getter to formulate the title of the seminar, a combination of the course number, seminar number, and course name.

Figure 1. The getter and setter methods for the name attribute of the Seminar class.




/**

* Returns the title of the seminar.

* The seminar title is the concatenation of the course number (CCC),

* the seminar number(SSS), and the name of the course(NNN) in the

* format "CCC-SSS NNN"

*

* @return String Title of the seminar

* @modifies yes Initializes the title of the seminar if not yet defined

* @example "CSC 158-2 Introduction to Java Programming"

*/

public String getTitle()

{
String newTitle = new String();

if ( name == null) {

// Build the name

newTitle += course.getNumber() + " ";

newTitle += getNumber();

newTitle += " " + course.getName();

setTitle(newTitle);

}

return this.title;

}

/**

* Sets the title of the seminar

*

* @param title

*

**/

private void setTitle(String title)

{

this.title = title;

}

The important thing to understand is that you don’t need to make all of your accessors public. Instead, you can define their visibility as you see fit. Unfortunately, this advice only holds for Java classes that aren’t beans — accessors that represent public JavaBean properties must be public as must accessors for persistent properties of an Enterprise JavaBean (EJB) under the 2.x EJB specification. Note that you may still have accessor methods for JavaBeans that do not have public visibility; it is just that the attributes that those accessors encapsulate cannot be accessed via the public interface of the bean (which is likely what you wanted to achieve in the first place). Similarly, EJB accessor methods that are not public imply that the attributes that they encapsulate cannot be persistent.

As an aside, the implementation of the getter, getTitle(), in Figure 1 is an example of lazy initialization, an approach where the value of an attribute is initialized (set) when it is first accessed. The advantage of this approach is you only incur the expense of obtaining the value when and if you need it. On the surface, this doesn’t appear like much of a savings for determining the seminar name, but it could be if the course object resided on another server, needed to be read in from persistent storage, and then needed to have its name transmitted across the network. The main disadvantage of lazy initialization is your code becomes more complex because you need to check to see if the attribute has been defined yet and, if not, obtain its value. Lazy initialization is typically used when an attribute is expensive to calculate or obtain (perhaps it is very large and would take significant time to transmit across the network) and when it is not always required each time the object is brought into memory.

The implementation of the setter, setTitle(), in Figure 1 is interesting from a naming convention point of view, a topic that I discussed in "Java naming conventions." The parameter is named the same as the instance attribute (field) itself, in this case title. This is what is called a naming collision, one that is luckily resolved by preceding the instance attribute with "this." . A better approach in this case may have been simply to use a different name for the text parameter, such as aTitle or newTitle, so as not to have this problem in the first place.

Resources

  • Building Object Applications That Work: Your Step-By-Step Handbook for Developing Robust Systems with Object Technology by Scott W. Ambler. New York: Cambridge University Press, 1998.
  • Process Patterns — Building Large-Scale Systems Using Object Technology by Scott Ambler. New York: Cambridge University Press, 1998.
  • The Object Primer 2nd Edition by Scott W. Ambler. New York: Cambridge University Press, 2000.
  • The Unified Process Construction Phase by Scott W. Ambler and Larry L. Constantine. Gilroy, CA: R&D Books, 2000.
  • Enterprise JavaBeans Specification Version 2.0 by L.G. DeMichiel, L.U. Yalcinalp, and S. Krishnan. 2000.
  • –>The Java Language Specification –> by James Gosling, Bill Joy, and Guy Steele. Reading, MA: Addison-Wesley Longman, Inc., 1996.
  • Advanced Java: Idioms, Pitfalls, Styles and Programming Tips by Chris Laffra. Upper Saddle River, NJ: Prentice Hall Inc., 1997.
  • Essential Java Style: Patterns for Implementation by Jeff Langr. Upper Saddle River, NJ: Prentice-Hall PTR, 1999.
  • –>Java 2 Performance and Idiom Guide: Guidelines for Java 2 Performance, Coding, and Testing –> by Craig Larman and Rhett Guthrie. Upper Saddle River, NJ: Prentice Hall Inc., 2000.
  • Object-Oriented Software Construction, Second Edition by Bertrand Meyer. Upper Saddle River, NJ: Prentice-Hall PTR, 1997.
  • Mastering JavaBeans by Laurence Vanhelsuwe. San Francisco: Sybex Inc., 1997.
  • The Elements of Java Style by Alan Vermeulen, Scott W. Ambler, Greg Bumgardner, Eldon Metz, Trevor Misfeldt, Jim Shur, and Patrick Thompson. New York: Cambridge University Press, 2000.
  • 2010-05-26T17:18:00+00:00 March 5th, 2003|Java|0 Comments

    About the Author:

    Scott W. Ambler is President of Ronin International, a consulting firm specializing in object-oriented software process mentoring, architectural modeling, and Enterprise JavaBeans (EJB) development. He has authored or co-authored several books about object-oriented development, including the recently released The Object Primer 2nd Edition, which covers, in detail, the subjects summarized in this article. He can be reached at scott.ambler@ronin-intl.com and at his Web site at www.ambysoft.com.

    Leave A Comment