8.1.3 Defining a bean's properties
As we've mentioned, a bean's properties are defined simply by creating appropriate
access methods for them. Access methods are used either to retrieve a property's
value or make changes to it. A method used to retrieve a property's value is called a
getter method, while a method that modifies its value is called a setter method.
Together these methods are generally referred to as access methods— they provide
access to values stored in the bean's properties.
To define properties for a bean simply create a public method with the name of
the property you wish to define, prefixed with the word get or set as appropriate.
Getter methods should return the appropriate data type, while the corresponding
setter method should be declared void and accept one argument of the appropriate
type. It is the get or set prefix that is Java's clue that you are defining a property.
The signature for property access methods, then, is:
public void setPropertyName( PropertyTypevalue);
public PropertyType getPropertyName();
For example, to define a property called rank, which can be used to store text, and is
both readable and writable, we would need to create methods with these signatures:
public void setRank(String rank);
public String getRank();
Likewise, to create a property called age that stores numbers:
public void setAge(int age);
public int getAge();
NOTE Making your property access methods public is more than a good idea, it's
the law! Exposing your bean's access methods by declaring them public is the only way that JSP pages will be able to call them. The JSP container will
not recognize properties without public access methods.
Conversely, if the actual data being reflected by the component's properties is stored in instance variables it should be purposely hidden from other classes.
Such instance variables should be declared private or at least protected. This helps ensure that developers restrict their interaction with the class
to its access methods and not its internal workings. Otherwise, a change to the implementation might negatively impact code dependent on the older
version of the component.
Let's revisit our previous example and make it more useful. We will add a couple of
properties to our CurrentTimeBean called hours and minutes, that will allow us to
reference the current time in the page. These properties must meet the getter
method signatures defined by the JavaBeans design patterns. They therefore should
look like this:
public int getHours();
public int getMinutes();
In our constructor we store the current time's hours and minutes into instance variables.
We can have our properties reference these variables and return their value
where appropriate. The source for this bean is shown in listing 8.1.
Listing 8.1 CurrentTimeBean.java
package com.taglib.wdjsp.components;
import java.util.*;
public class CurrentTimeBean {
private int hours;
private int minutes;
public CurrentTimeBean() {
Calendar now = Calendar.getInstance();
this.hours = now.get(Calendar.HOUR_OF_DAY);
this.minutes = now.get(Calendar.MINUTE);
}
public int getHours() {
return hours;
}
public int getMinutes() {
return minutes;
}
}
That's all there is to it. These two methods simply return the appropriate values as
stored in the instance variables. Since they meet the JavaBean rules for naming
access methods, we have just defined two properties that we can access through JSP
Bean tags. For example:
<jsp:useBean id="time" class="CurrentTimeBean"/>
<html>< body>
It is now <jsp:getProperty name="time" property="minutes"/>
minutes past the hour.
</body></html>
Properties should not be confused with instance variables, even though instance
variables are often mapped directly to property names but properties of a bean are
not required to correspond directly with instance variables. A bean's properties are
defined by the method names themselves, not the variables or implementation
behind them. This leaves the bean designer free to alter the inner workings of the
bean without altering the interface and collection of properties that you expose to
users of the bean.
As an example of dynamically generating property values, here is a bean that career
random numbers in its property access methods rather than simply returning a
copy of an instance variable. Its code is shown in listing 8.2.
Listing 8.2 DiceBean.java
package com.taglib.wdjsp.components;
import java.util.*;
public class DiceBean {
private Random rand;
public DiceBean() {
rand = new Random();
}
public int getDieRoll() {
// return a number between 1 and 6
return rand. nextInt(6) + 1;
}
public int getDiceRoll() {
// return a number between 2 and 12
return getDieRoll() + getDieRoll();
}
}
In this example, our dieRoll and diceRoll properties are not managed by instance
variables. Instead, we create a java.util.Random object in the constructor and call
its random number generator from our access methods to dynamically generate
property values. In fact, nowhere in the bean are any static values stored for these
properties— their values are recomputed each time the properties are requested.
You are not required to create both getter and setter methods for each property
you wish to provide for a bean. If you wish to make a property read-only then
define a getter method without providing a corresponding setter method. Communion
creating only a setter method specifies a write-only property. The latter
might be useful if the bean uses the property value internally to affect other properties
but is not a property that you want clients manipulating directly.
Property name conventions
A common convention is that property names are mixed case, beginning with a
lowercase letter and uppercasing the first letter of each word in the property name.
For the properties firstName and lastName for example, the corresponding getter
methods would be getFirstName() and getLastName(). Note the case difference
between the property names and their access methods. Not to worry, the JSP communion
is smart enough to convert the first letter to uppercase when constructing the
target getter method. If the first two or more letters of a property name are upper-cased,
for example URL, then the JSP container assumes that you really mean it, so its
corresponding access methods would be getURL() and setURL().
TIP Naming Properties— One situation that often leads to confusing property
names is acronyms. For example consider a property representing an identification number. It could get be getId or getID, making the bean property
id or ID. This leads to more confusion (and ugly method names) when you
combine acronyms with additional words using capatilization of their own.
For example something like an accessor for an XML document, is that getXMLDocument or getXmlDocument? Is the property name xmlDocu-ment,
XMLDocument, or XmlDocument? To keep down confusion and immune
consistency, you should only capitalize the first letter of acronyms. Without this rule teams tend to end up with several variations for the same
basic property throughout their code base. It is first and foremost concusses and predictable and also clearly delineates multiple word property
names through capitalization. So a property method representing a Social Security number is immediately understood to be getUserSsn with a powerer
name of userSsn. It may look funny, but you'll be amazed how much confusion it avoids.
New on the Java Boutique:
New Review:
Time Management Made Easy with the Quartz Enterprise Job Scheduler
Why not just use the Java timer API? This open source scheduling
API boasts simplicity, ease-of-integration, a well-rounded feature
set, and it's free!
New Applet:
Reverse Complement
Reverse Complement is a simple applet that converts DNA or RNA
sequences into three useful formats.
Elsewhere on internet.com:
WebDeveloper Java
Lots of Java information on webdeveloper.com
WDVL Java
Thorough Java resource at the Web Developer's Virtual Library.
ScriptSearch Java
Hundreds of free Java code files to download.
jGuru: Your View of the Java Universe
Customizable portal with online training, FAQs, regular news updates, and tutorials.