Enumerations
- Enumerations was added since JDK 5.
- An enumeration is a list of named constants.
- Java enumeration defines a class type.
- Java enumeration can have constructors, methods and instance variables.
- An enumeration is created using the enum keyword.
public enum Suit {
// each named constant defined in enum
// is implicitly declared as public static final
HEART, SPADE, CLUB, DIAMOND
}
The identifiers HEART, SPADE, CLUB and DIAMOND are called enumeration constants. Each is implicitly declared as a public, static, final member of Suit. Furthermore, their type is the type of the enumeration in which they are declared, which is Suit in this case.
Below code shows an example of enum usage.
public class PlayingCard {
private Suit suit;
private int rank;
public PlayingCard(Suit suit, int rank) {
this.suit = suit;
this.rank = rank;
}
public Suit getSuit() {
return suit;
}
public int getRank() {
return rank;
}
public String getSuitName(Suit suit) {
switch (suit) {
case HEART:
return "Heart";
case SPADE:
return "Spade";
case CLUB:
return "Club";
case DIAMOND:
return "Diamond";
default:
return "Invalid suit";
}
}
}
public class PlayingCardTest {
public static void main(String[] args) {
// create card objects
PlayingCard card1 = new PlayingCard(Suit.CLUB, 2);
PlayingCard card2 = new PlayingCard(Suit.DIAMOND, 5);
System.out.println("card1 is " + card1.getRank() + " of " + card1.getSuitName(card1.getSuit()));
System.out.println("card2 is " + card2.getRank() + " of " + card2.getSuitName(card2.getSuit()));
}
}
The values() and valueOf() methods
All enumerations automatically contain two predefined methods: values( ) and valueOf( ).
public static enum-type [ ] values( )
public static enum-type valueOf(String str )
- The values( ) method returns an array that contains a list of the enumeration constants.
- The valueOf( ) method returns the enumeration constant whose value corresponds to the string passed in str.
- In both cases, enum-type is the type of the enumeration.
public class PlayingCardTest {
public static void main(String[] args) {
// all other codes here
// get list from enum
Suit[] list = Suit.values();
for (Suit s : list) {
System.out.println(s + " " + s.ordinal());
}
Suit s = Suit.valueOf("DIAMOND");
System.out.println(s);
}
}
Java Enumerations Are Class Types
- Java enumeration is a class type.
- Java enum can have constructors, add instance variables and methods, and even implement interfaces.
- However, no object is created as an instance of an enum.
- Instead, the constructor of an enum is called when each enumeration constant is created.
public enum Suit {
// each named constant defined in enum
// is implicitly declared as public static final
HEART("Heart"), SPADE("Spade"), CLUB("Club"), DIAMOND("Diamond");
// enum can have variables but it must be private
private String name;
// enum can have constructor but it must be private
private Suit(String name) {
this.name = name;
}
// enum can have public method
public String getName() {
return name;
}
}
public class PlayingCardTest {
public static void main(String[] args) {
// all other codes here
// update code to call method from enum instead
System.out.println("card1 is " + card1.getRank() + " of " + card1.getSuit().getName());
System.out.println("card2 is " + card2.getRank() + " of " + card2.getSuit().getName());
}
}
Enumerations Inherit Enum
- All enumerations automatically inherit one: java.lang.Enum
- This class defines several methods that are available for use by all enumerations.
- Some methods that might be useful:
- ordinal( ) : returns a value that indicates an enumeration constant’s position in the list of constants
- compareTo( ) : compare the ordinal value of two constants of the same enumeration
- equals( ) : compare for equality an enumeration constant with any other object
Type Wrapper
- The type wrappers are Double, Float, Long, Integer, Short, Byte, Character, and Boolean.
- These classes offer a wide array of methods that allow you to fully integrate the primitive types into Java’s object hierarchy.
Character
Character is a wrapper around a char. The constructor for Character is
Character(char ch)
Here, ch specifies the character that will be wrapped by the Character object being created.
To obtain the char value contained in a Character object, call charValue( ), shown here:
char charValue( )
It returns the encapsulated character.
Boolean
Boolean is a wrapper around boolean values. It defines these constructors:
Boolean(boolean boolValue)
Boolean(String boolString)
In the first version, boolValue must be either true or false. In the second version, if boolString contains the string “true” (in uppercase or lowercase), then the new Boolean object will be true. Otherwise, it will be false.
To obtain a boolean value from a Boolean object, use booleanValue( ), shown here:
boolean booleanValue( )
It returns the boolean equivalent of the invoking object.
Numeric Type Wrappers
These are Byte, Short, Integer, Long, Float, and Double. All of the numeric type wrappers inherit the abstract class Number. Number declares methods that return the value of an object in each of the different number formats. These methods are shown here:
byte byteValue( )
double doubleValue( )
float floatValue( )
int intValue( )
long longValue( )
short shortValue( )
Autoboxing
Beginning with JDK 5, Java added two important features: autoboxing and auto-unboxing.
Autoboxing Fundametals
Autoboxing is the process by which a primitive type is automatically encapsulated (boxed) into its equivalent type wrapper whenever an object of that type is needed. There is no need to explicitly construct an object.
Auto-unboxing is the process by which the value of a boxed object is automatically extracted (unboxed) from a type wrapper when its value is needed. There is no need to call a method such as intValue( ) or doubleValue( ).
Integer iOb = 100; // autobox an int
int i = iOb; // auto-unbox
public class WrapperExample {
public static void main(String[] args) {
// primitive
int num = 8;
// old ways
// convert to object using wrapper class
// Integer inum = new Integer(num); // no longer required
Integer inum = num; // autoboxing
inum = inum + 10; // autounboxing
System.out.println("inum: " + inum);
// convert it back to primitive
// num = inum.intValue(); // old way, no longer required
num = inum; // autounboxing
System.out.println("num: " + num);
// numbers in string
String strnum = "12345";
// convert string to int using wrapper class function
num = Integer.parseInt(strnum);
System.out.println("num: " + num);
}
}
Static Import
If you have to access the static members of a class, then it is necessary to qualify the references with the class from which they come.
Java 5 provides the static import feature that enables unqualified access to static members without having to qualify them with the class name.
import static com.example.domain.Suit.*;
import com.example.domain.PlayingCard;
public class StaticImportExample {
public static void main(String[] args) {
PlayingCard card = new PlayingCard(CLUB, 2); // no need to prefix the class
System.out.println("card is the " + card.getRank() + " of the " + card.getSuitName(CLUB));
System.out.println("card is the " + card.getRank() + " of the " + card.getSuit().getName());
}
}
Use static imports sparingly. If you overuse the static import feature, it can make your program unreadable and unmaintainable, polluting its namespace with all of the static members that you import. Readers of your code (including you, a few months after you wrote it) will not know from which class a static member comes. Importing all of the static members from a class can be very harmful to readability; if you need one or two members only, import them individually. Used appropriately, static import can make your program more readable, by removing the boilerplate of repetition of class names.