When should I use enum



9.6 The special upper class Enum

Each enumeration type inherits from the special class. Let's take the days of the week again [194] (Java SE also declares an enumeration type for days of the week including methods that should be preferred in productive software. We reproduce it because it is so clear.

Listing 9.34 com / tutego / insel / enumeration / Weekday.java, Weekday

public enum Weekday {

MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY

}

The compiler translates this into a class that looks something like this:

public class Weekday extends Enum {



public static final Weekday MONDAY = new Weekday ("MONDAY", 0);

public static final Weekday TUESDAY = new Weekday ("TUESDAY", 1);

// more constants ...



private Weekday (String s, int i) {

super (s, i);

}



// more methods ...

}


9.6.1Methods on enum objects

Each object automatically has some standard methods that come from the superclass. On the one hand there are overridden methods, some new object methods and some static methods.

Figure 9.8 Type relationship of Enum

String representation

An object returns the name of the constant via the method. In addition, there is the well-known method, which is called by default but can be overridden. The method cannot be overwritten.

A compiler-generated class provides a static method that returns the object that matches the representation. If a string is passed for which there is no string, it is followed by a. There is also another static method, which is declared in the class itself (the base class of the classes generated by the compiler):.

[eg] example

The conversion to the string and from the string to the corresponding object:

System.out.println (Weekday.MONDAY.toString ()); // MONDAY

System.out.println (Weekday.MONDAY.name ()); // MONDAY

System.out.println (Weekday.valueOf ("MONDAY"). Name ()); // MONDAY

System.out.println (Enum.valueOf (Weekday.class, "MONDAY"). Name ()); // MONDAY

The difference to the methods is important: While there is only one time, static methods exist once in each enumeration class generated by the compiler. Since the method is compiler-generated, it does not appear in the following list:

abstract class java.lang.Enum >

implements Comparable , Serializable


  • Returns the name of the constant. Since the method - like many others in the class - is final, the name cannot be changed.



  • Returns the name of the constant. The method calls in a standardized way, but because it is not final, it can be overwritten.



  • Enables you to search for objects for a constant name and class. It returns the object for the given string or triggers one if no object can be assigned to the string.

List all constants of the class

A practical static method is. It returns an array of all enumerations of the enumeration type. This is useful for the extended one that is supposed to enumerate all constants. An alternative with the same result is the method:

Listing 9.35 com / tutego / insel / enumeration / WeekdayDemo.java, excerpt main ()

for (Weekday day: Weekday.values ​​()) // or Weekday.class.getEnumConstants ()

System.out.println ("Name =" + day.name ());

Returns lines with ...

Ordinal number

Each enumeration inherits a protected parameterized constructor from the superclass, which expects the name of the constant and an associated counter. Each element of the enumeration becomes an object of the basic type that stores a name and an ID, the so-called ordinal number. Of course, it can also be asked for its name and counter.

[eg] example

A method that returns the ordinal number of an element of the enumeration or -1 if the constant does not exist:

Listing 9.36 com / tutego / insel / enumeration / WeekdayDemo.java, getOrdinal ()

static int getOrdinal (String name) {

try {

return Weekday.valueOf (name) .ordinal ();

}

catch (IllegalArgumentException e) {

return -1;

}

}

Our and.

The ordinal number indicates the position in the declaration and is also the ordering criterion for the method. The ordinal number cannot be changed and always represents the order of the declared constants.

[eg] example

Does Monday really come before Friday?

System.out.println (Weekday.MONDAY.compareTo (Weekday.FRIDAY)); // -4

System.out.println (Weekday.MONDAY.compareTo (Weekday.MONDAY)); // 0

System.out.println (Weekday.FRIDAY.compareTo (Weekday.MONDAY)); // 4

Negative returns at always indicate that the first object is "smaller" than the second from the argument.

abstract class java.lang.Enum >

implements Comparable , Serializable


  • Returns the ID belonging to the constant. In general, this ordinal number is not important, but special data structures such as or use this unique ID. The order of the numbers is given by the order in which they are specified.



  • The superclass overwrites with the logic as in - that is, comparing the references - to mark it as.



  • The method is and can therefore neither be overwritten nor called from outside. So there can be no copies of the objects that could endanger the identity. In principle, however, it is allowed if your own implementations provide the reference.



  • Because the class implements the interface, the method also exists. It compares using the ordinals. Comparisons are only allowed within one type.



  • Returns the object from the enumeration class to a concrete. Caution: The method, when used on the enumeration class itself, delivers a meaningful value and only on the elements of the enumeration. That would be the same, but as desired.

["]Note

The method of the object is still interesting because it also returns like an array with all entries. The advantage over the object, however, is that it is more generic; the call to the static method is always associated with the class, works on any object, and even if it shouldn't represent an enumerated class, the return is.



9.6.2 Lists with their own methods and initializers *

Since a type is a special form of class declaration, it can also declare attributes, methods, static or object initializers and constructors. Each enumeration automatically has methods like and, and developers can add their own there too.

Country with an additional class method

An enumeration type can have static methods. These methods can access static properties of the enumeration type and, for example, select constants. is such a given static method that returns an array of all enumeration elements.

[eg] example

Declare an enumeration and two static methods such that yields and a random country:

public enum Country {

GERMANY, UK, CHINA;

public static Country getDefault () {return GERMANY; }

public static Country random () {return values ​​() [(int) (Math.random () * 3)]; }

}

Additional static initialization

Blocks of this type are allowed in the body of an enumeration type. Loads the runtime environment of a class, initializes all static variables one after the other or executes the blocks. The lists are static variables and are initialized when loading. If the static initializer is behind the constants, it will also be called later than the constructors, which may want to use static variables that the block initializes. An example:

public enum Country {



GERMANY, UK, CHINA;



{

System.out.println ("Object Initializer");

}



static {

System.out.println ("class initializer");

}



private Country () {

System.out.println ("Constructor");

}



public static void main (String [] args) {

System.out.println (GERMANY);

}

}

The output is:

Object initializer

Constructor

Object initializer

Constructor

Object initializer

Constructor

Class initializer

GERMANY

The execution and output depends on the order of the declaration, and each reorganization leads to a change in behavior. Now programmers might come up with the idea of ​​putting possible blocks at the beginning, before the constants. My readers should test the result ...

We'll come back to constructors in a moment.

Country with an additional object method

Let's give an enumeration a method that returns the ISO 3166-2 country code of the respective enumeration element:

Listing 9.37 com / tutego / insel / enumeration / Country.java, Country

public enum Country {



GERMANY, UK, CHINA;



publicStringgetISO3Country () {

if (this == GERMANY)

return "DEU";

else if (this == UK)

return "GBR";

return "CHN";

}

}

The method can now be called on the enumeration:

System.out.println (Country.CHINA.getISO3Country ()); // CHN

Since enumerations are allowed, we can write the following demo program:

Listing 9.38 com / tutego / insel / enumeration / CountryEnumDemo.java, excerpt

Country c = Country.GERMANY;



switch (c) {

case GERMANY:

System.out.println ("Aha. Ein Krauti"); // Aha. A krauti

System.out.println (c.getISO3Country ()); // DEU

break;

default:

System.out.println ("Other Country");

}


9.6.3enum with its own constructors *

In addition to the first variant for, we want to use a second implementation and now use constructors to solve the same problem in a different way:

Listing 9.39 com / tutego / insel / enumeration / Country2.java, Country2

public enum Country2 {



GERMANY ("DEU"),

UK ("GBR"),

CHINA ("CHN");



private string iso3Country;



Country2 (Stringiso3Country) {

this.iso3Country = iso3Country;

}



public string getISO3Country () {

return iso3Country;

}

}

When declaring the constants, an argument for the constructor is passed in round brackets. The constructor saves the string in the internal variable, which is then referred to.

["]Note

Enumerated type constructors are always automatically private and cannot have any other visibility. That is logical, because the constructors should not be able to be called from outside. The methods can definitely have different visibilities.

enum with overridden methods

In the enumeration type, not only can methods be added, but methods can also be overwritten. Let's start with a localized and cluttered method:

Listing 9.40 com / tutego / insel / enumeration / WeekdayInternational.java, WeekdayInternational

public enum Weekday International {



SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY;



@Override

publicStringtoString () {

return toString (Locale.getDefault ());

}



publicStringtoString (Localel) {

return new SimpleDateFormat ("", l) .getDateFormatSymbols ()

.getWeekdays () [ordinal () + 1];

}

}

The first method has been overwritten from our superclass, the second added as an overloaded method. An example makes the call and the functionality clear:

Listing 9.41 com / tutego / insel / enumeration / WeekdayInternationalDemo.java, main ()

System.out.println (WeekdayInternational.SATURDAY);

// Saturday

System.out.println (WeekdayInternational.SATURDAY.toString ());

// Saturday

System.out.println (WeekdayInternational.SATURDAY.toString (Locale.FRANCE));

// samedi

System.out.println (WeekdayInternational.SATURDAY.toString (Locale.ITALY));

// sabato

The possibilities of the syntax do not stop at this point. Similar to the syntax of inner anonymous classes, which allow methods to be overridden, enumeration types offer a comparable syntax for overwriting methods for a specific constant in a targeted manner.

Let's assume that a game has its own currency, the ponro dollar. But now this should be related to a reference currency, the euro; the exchange rate is simply 1: 2:

Listing 9.42 com / tutego / insel / enumeration / GameCurrency.java, GameCurrency

public enum GameCurrency {



EURO() {

@OverridepublicdoubleconvertTo (GameCurrencytargetCurrency, doublevalue) {

returntargetCurrency == EURO? value: value / 2;

}

},

PONRODOLLAR () {

@OverridepublicdoubleconvertTo (GameCurrencytargetCurrency, doublevalue) {

returntargetCurrency == PONRODOLLAR? value: value * 2;

}

};



publicabstractdoubleconvertTo (GameCurrencytargetCurrency, doublevalue);

}

The interesting part is the declaration of the abstract method and the implementation locally for the individual constants. (Of course we don't have to make every method abstract, but it can also be concrete. Then not every element has to implement the abstract method.)

With a static import for the enumeration, the usage and functionality can be shown quickly:

Listing 9.43 com / tutego / insel / enumeration / GameCurrencyDemo.java, main ()

System.out.println (EURO.convertTo (EURO, 12)); // 12.0

System.out.println (EURO.convertTo (PONRODOLLAR, 12)); // 6.0

System.out.println (PONRODOLLAR.convertTo (EURO, 12)); // 24.0

System.out.println (PONRODOLLAR.convertTo (PONRODOLLAR, 12)); // 12.0

enum can implement interfaces

The API documentation for indicates that the abstract class implements two interfaces: and. Every constant declared in is a subclass of, i.e. always comparable and serializable by default. In addition to these standard interfaces, another interface can be implemented. This is very useful because it prescribes a certain behavior for all enumeration elements - each enumeration element then offers these operations. The interface operations can be implemented in two ways: The interface itself implements the interface operations in the body, or the individual enumeration elements implement the implementations differently. It is often the case that the elements provide different implementations.

Our next example of one implements the graphical symbol interface. Since the symbols all have the same dimensions, the -operations and are always the same and are only implemented once; the actual implementations (which are only hinted at here) differ.

Listing 9.44 com / tutego / insel / enumeration / DefaultIcons.java, DefaultIcons

public enum DefaultIcons implementsIcon {



WARNING {

@OverridepublicvoidpaintIcon (Componentc, Graphicsg, intx, inty) {

// g.drawXXX ()

} },

ERROR {

@OverridepublicvoidpaintIcon (Componentc, Graphicsg, intx, inty) {

// g.drawXXX ()

} };



@OverridepublicintgetIconWidth () {return 16; }



@OverridepublicintgetIconHeight () {return 16; }

}

Access gives an object that is of the type, among other things, and can be transferred at all points where one is desired.

How did you like the ? We always look forward to your friendly and critical feedback.

>> To the feedback form