The
java.util.Properties
class is a
specialized
hashtable
for strings. Java uses the
Properties
object to replace the environment
variables used in other programming environments. You can use a
Properties
object (or “table”) to hold
arbitrary configuration information for an application in an easily
accessible format. The Properties
object can also
load and store information using streams (see Chapter 10, for information on streams).
Any string values can be stored as key/value pairs in a
Properties
table. However, the convention is to
use a
dot-separated naming hierarchy to
group property names into logical structures, as is done with X
Window System resources on Unix systems.[36] The java.lang.System
class provides system-environment information in this way, through a
system Properties
table we’ll describe
shortly.
Create an empty Properties
table and add
String
key/value pairs just as with any
Hashtable
:
Properties props = new Properties( ); props.put("myApp.xsize", "52"); props.put("myApp.ysize", "79");
Thereafter,
you can retrieve values with the getProperty( )
method:
String xsize = props.getProperty( "myApp.xsize" );
If the named property doesn’t exist,
getProperty( )
returns null
.
You can get an Enumeration
of the property names
with the propertyNames( )
method:
for ( Enumeration e = props.propertyNames( ); e.hasMoreElements; ) { String name = e.nextElement( ); ... }
When you create a
Properties
table, you can specify a second table
for default property values:
Properties defaults; ... Properties props = new Properties( defaults );
Now when you call getProperty( )
,
the method searches the default table if it doesn’t find the
named property in the current table. An alternative version of
getProperty( )
also accepts a default value; this
value instead of null
is returned, if the property
is not found in the current list or in the default list:
String xsize = props.getProperty( "myApp.xsize", "50" );
You can save a
Properties
table to an OutputStream
using
the save( )
method. The property information is
output in flat ASCII format. Continuing with the previous example,
output the property information to System.out
as
follows:
props.save( System.out, "Application Parameters" );
System.out
is a standard output stream similar to
C’s stdout
. We could also save the
information to a file by using a FileOutputStream
as the first argument to save( )
. The second
argument to save( )
is a String
that is used as a header for the data. The previous code outputs
something like the following to System.out
:
#Application Parameters #Mon Feb 12 09:24:23 CST 1999 myApp.ysize=79 myApp.xsize=52
The load( )
method reads the previously saved contents
of a
Properties
object from an
InputStream
:
FileInputStream fin; ... Properties props = new Properties( ) props.load( fin );
The list( )
method is
useful for debugging. It
prints the contents to an OutputStream
in a format
that is more human-readable but not retrievable by load( )
. It truncates long lines with an ellipsis
(...
).
The
java.lang.System
class
provides access to basic
system environment information through the static
System.getProperty( )
method. This method returns a
Properties
table that contains system properties.
System properties take the place of environment variables in some
programming environments. Table 9.8
summarizes system properties that are guaranteed to be defined in any
Java environment.
Table 9-8. System Properties
System Property |
Meaning |
---|---|
|
Vendor-specific string |
|
URL of vendor |
|
Java version |
|
Java installation directory |
|
Java class version |
|
The class path |
|
Operating system name |
|
Operating system architecture |
|
Operating system version |
|
File separator (such as |
|
Path separator (such as |
|
Line separator (such as |
|
User account name |
|
User’s home directory |
|
Applets are, by current web
browser conventions, prevented from reading the following properties:
java.home
, java.class.path
,
user.name
, user.home
, and
user.dir
. As you’ll see later, these
restrictions are implemented by a SecurityManager
object.
Your
application can set system properties with the static method
System. setProperty( )
. You can also set system
properties when you run the Java interpreter, using the
-D
option:
%java -Dfoo=bar -Dcat=Boojum MyApp
Since it is common to use system properties to provide parameters
such as numbers and colors, Java provides some convenience routines
for retrieving property values and parsing them into their
appropriate types. The classes Boolean
,
Integer
, Long
, and
Color
each come with a “get” method
that looks up and parses a system property. For example,
Integer.getInteger("foo")
looks for a system
property called foo
and then returns it as an
Integer
. Color.getColor("foo")
parses the property as an RGB value and returns a
Color
object.
The java.util.Observer
interface and java.util.Observable
class
are relatively small utilities, but they provide a peek at a
fundamental design pattern. The concept of observers and observables
is part of the
MVC (Model
View Controller) framework. It is an abstraction that lets a number
of client objects (the observers) be notified
whenever a certain object or resource (the
observable) changes in some way. We will see
this pattern used extensively in Java’s event mechanism.
The basic idea behind observers and observables is that the
Observable
object has a method that an
Observer
calls to register its interest. When a
change happens, the Observable
sends a
notification by calling a method in each of the
Observer
s. The observers implement the
Observer
interface, which specifies that
notification causes an Observer
object’s
update( )
method
to be called.
In the following example, we create a MessageBoard
object that holds a String
message.
MessageBoard
extends
Observable
, from which it inherits the mechanism
for registering observers (addObserver( )
)
and notifying observers (notifyObservers( )
).
To observe the MessageBoard
, we have
Student
objects that implement the
Observer
interface so that they can be notified
when the message changes:
//file: MessageBoard.java import java.util.*; public class MessageBoard extends Observable { private String message; public String getMessage( ) { return message; } public void changeMessage( String message ) { this.message = message; setChanged( ); notifyObservers( message ); } public static void main( String [] args ) { MessageBoard board = new MessageBoard( ); Student bob = new Student( ); Student joe = new Student( ); board.addObserver( bob ); board.addObserver( joe ); board.changeMessage("More Homework!"); } } // end of class MessageBoard class Student implements Observer { public void update(Observable o, Object arg) { System.out.println( "Message board changed: " + arg ); } }
Our MessageBoard
object extends
Observable
, which provides a method
called
addObserver( )
. Each of our
Student
objects registers itself using this method
and receives updates via its update( )
method.
When a new message string is set, using the
MessageBoard
’s changeMessage( )
method, the Observable
calls the
setChanged()
and notifyObservers( )
methods to notify the
observers. notifyObservers( )
can take as an
argument an Object
to pass along as an indication
of the change. This object, in this case the
String
containing the new message, is passed to
the observer’s update( )
method, as its
second argument. The first argument to update( )
is the Observable
object itself.
The main( )
method of
MessageBoard
creates a
MessageBoard
and registers two
Student
objects with it. Then it changes the
message. When you run the code, you should see each
Student
object print the message as it is
notified.
You can imagine how you could implement the observer/observable
relationship yourself using a Vector
to hold the
list of observers. In Chapter 13, and beyond,
we’ll see that the Swing
event model extends
this design patttern to use strongly typed notification
objects and
observers; these are events and event
listeners.
[36] Unfortunately, this is just a naming convention right now, so you can’t access logical groups of properties as you can with X resources.
Get Learning Java now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.