|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 5 of 6
int myColor = Color.Red;
But, what is to prevent someone from doing the following?
int myColor = 999;
Obviously the compiler will not (and cannot) catch this error, which quite possibly will lead to a runtime exception.
Here's an alternative implementation of the Color class that solves the problem mentioned above:
// The new Color class
public class Color
{
// Color value;
int _color;
// Constructor
protected Color (int color)
{
_color = color;
}
public static final int _Red = 1;
public static final int _White = 2;
public static final int _Blue = 3;
public static final Color Red = new Color(_Red);
public static final Color White = new Color(_White);
public static final Color Blue = new Color(_Blue);
}
And here is how you would use it:
Color myColor = Color.Red;
The above implementation ensures that invalid colors cannot be specified. However, we did a lot of work and our solution remains
limited. J2SE 1.5 provides a better solution with its addition of enumerations; a concept C and C++ programmers are already
familiar with. Let's rewrite the Color class using enumerations:
// The color enumeration
public enum Color
{
Red,
White,
Blue
}
Notice the usage of the keyword enum instead of class. Also, notice how simple the implementation has become. Here's how you could use the Color enumeration in your code:
// Using the Color enumeration Color myColor = Color.Red;
The usage is the same as the usage of our second example (above), but the enumeration is much more capable than our simple
Color class implementation. For example, all enumerations have a static method called values() that returns all the enumeration values in a collection as shown in the code fragment below:
// Cycling through the values of an enumeration
for (Color c : Color.values())
System.out.println(c);
The above code fragment produces the following output:
Red White Blue
All enumerations also have another static method called valueOf() that returns the enumeration constant corresponding to a string parameter. For example Color.valueOf("Red") returns Color.Red.
In addition, each enumeration has several useful instance methods. The name() method returns the enumeration constant's name, exactly as declared in its declaration. For example, Color.Red.name() returns Red. The toString() method returns the same value as name(), but can be overridden to provide a better and more friendlier or meaningful (and even internationalized) name. The ordinal() method returns the zero-based position of the declared constant. For example, Color.White.ordinal() returns 1. Finally, the compareTo() method compares the current enumeration object (i.e., this) with the specified enumeration object and returns a negative integer, zero, or a positive integer, depending on whether
the current enumeration object is less than, equal to, or greater than the specified object, respectively. The comparison
is based on the ordinal of the declared enumeration constants. For example, Color.Red.compareTo(Color.White) will return -1.
Enumerations can have constructors and methods as well. For example, let's say I wanted to provide a friendlier name than
offered by the default toString() implementation. Here's an example that accomplishes that:
// The revised color enumeration
public enum Color
{
Red("Red (#FF0000)"),
White("White (#000000)"),
Blue("Blue (#0000FF)"),
Green("Green (#00FF00)")
{
public boolean isInUSFlag()
{
return false;
}
};
private String newName;
Color(String s)
{
newName = s;
}
public String toString()
{
return newName;
}
public boolean isInUSFlag()
{
return true;
}
}
Note that I also added a new color, Green, and a new method called isInUSFlag() that by default returns true. Since green is not in the US flag, I override the isInUSFlag() method when I declare the constant Green and return false from the overridden method implementation.
The last new language feature explained in this article is the static import. Static imports are yet another convenience feature
added to version 1.5 that extends the way imports work in Java. For example, consider the code fragment shown below that calls
the static ceil() method on the java.lang.Math class
// x is a number of type double such as 5.345 double y = Math.ceil(x);
With static imports in 1.5, you can ask the Java compiler to import only a class's static portions, as shown, for example, in the rewritten code fragment below:
// Import declaration at the top of the class along with the other imports import static java.lang.Math.ceil; // And then somewhere in the code... // x is a number of type double such as 5.345 double y = ceil(x);
In the above fragment, I used the new static import feature to import the static method ceil() from the Math class. Now when I call the method, I don't have to qualify it with Math. If I wanted to use multiple static methods from the Math class, I could import them individually or all at once as shown below:
// Import all static methods from Math import static java.lang.Math.*;
This also applies to any constants declared within Math, such as E and PI. With the above declaration, I can use these constants as if they were declared locally within my class (or superclass).
Finally, static imports can be used with enumerations as well. For example, consider the following enumeration definition:
package myEnumerations;
public enum Color
{
Red,
White,
Blue
}
You may access this enumeration's values in (at least) one of the following two ways:
myEnumerations.Color and reference Color.Red in your code
myEnumerations.Color.* and reference Red in your code
This article has provided a quick introduction to a few of the new language features in J2SE 1.5. To be completely honest, none of these features introduce any groundbreaking or previously impossible functionality into the Java language. As we saw throughout the article, there were always workarounds. What the new features do provide are reduced code complexity, enhanced readability, and much better compile-time type safety. However, if I had to choose one feature that most impresses me, I would select enumerations. In my opinion, Sun and the Java team have done an excellent job with its implementation of enumerations by making it extremely close to a first-class class within Java, thus enabling enumerations to have constructors, methods, and method overriding.
Archived Discussions (Read only)
(