Creating a finite type
[comp1110-2M] - Liam O'Connor, Fabian Muehlboeck
Creating a finite type
[comp1110-2M]- Liam O'Connor, Fabian Muehlboeck
Definition 1. Enums
[comp1110-2G] - Liam O'Connor, Fabian Muehlboeck
Definition 1. Enums
[comp1110-2G]- Liam O'Connor, Fabian Muehlboeck
An enum (short for enumeration) is a user-definable type whose values come from a fixed finite list. Instead of using arbitrary integers or strings, we define a small set of allowed values and give each one a name. For example:
This defines a new type called Month. A variable of type Month can only hold one of these twelve values. For example:
The names (which are by convention written in ALL_CAPS) inside the enum definition are called constants.
They are always written with the type name in front, such as Month.JANUARY or Month.DECEMBER.
This prevents confusion if different enums contain constants with the same name.
2. The benefits of enums
[comp1110-2J] - Liam O'Connor, Fabian Muehlboeck
2. The benefits of enums
[comp1110-2J]- Liam O'Connor, Fabian Muehlboeck
One advantage of enums is that they help make illegal states unrepresentable.
If we represent months using integers or strings, the program could accidentally produce values that are not valid months (such as "Spring" or -2).
By defining a Month enum, we restrict the variable to a fixed set of valid values (JANUARY, FEBRUARY, MARCH, and so on).
The compiler then ensures that no other values can appear.
This prevents many kinds of mistakes and makes programs easier to reason about, because whenever we see a variable of type Month, we know it must be one of those twelve possibilities.
Example 3. A Month from User Input
[comp1110-2H] - Liam O'Connor, Fabian Muehlboeck
Example 3. A Month from User Input
[comp1110-2H]- Liam O'Connor, Fabian Muehlboeck
The final line in the above function also demonstrates that enum types have a built in .toString() method that converts to the string representation of the constant name.
Warning 4. Enums are reference types
[comp1110-2I] - Liam O'Connor, Fabian Muehlboeck
Warning 4. Enums are reference types
[comp1110-2I]- Liam O'Connor, Fabian Muehlboeck
In Java, enum values are technically things that reside in memory, like Strings and arrays: each constant such as Month.JANUARY or Month.AUGUST has its own place in memory.
However, for each constant there is exactly one object created by the Java runtime.
This means every time the program refers to Month.JANUARY, it refers to the same object.
Because there is only one instance of each constant, it is safe to compare enum values using ==.
The comparison simply checks whether the two references point to the same object, which correctly tells us whether the two enum values are the same.
Construction 5. The switch statement on enums
[comp1110-2K] - Liam O'Connor, Fabian Muehlboeck
Construction 5. The switch statement on enums
[comp1110-2K]- Liam O'Connor, Fabian Muehlboeck
Java provides a convenient way to perform different actions depending on an enum value: the switch statement.
The switch examines the value of g. Each line specifies what to do for one possible value. If m is Month.MARCH, for example, the program prints "Mar".
Notice that inside the switch we write the constants without the Month. prefix. Java already knows that m has type Month, so it knows which constants we mean.
Warning 6. The old-style switch statement
[comp1110-2L] - Liam O'Connor, Fabian Muehlboeck
Warning 6. The old-style switch statement
[comp1110-2L]- Liam O'Connor, Fabian Muehlboeck
Older versions of Java used a different syntax for switch statements:
This version uses case labels and colons, and each branch usually ends with break.
If break is omitted, execution falls through into the next case, which often causes mistakes.
Therefore, in this course we will use the arrow form and not the older colon style.
Construction 7. The switch expression on enums
[comp1110-76] - Liam O'Connor, Fabian Muehlboeck
Construction 7. The switch expression on enums
[comp1110-76]- Liam O'Connor, Fabian Muehlboeck
switch is a control structure, like if and while.
In contrast to these two, however, switch can also be used as an expression form, which means it
can be used as the right-hand side of an assignment. For example:
In this case, it is important that each case of the switch expression returns a value of a suitable type.
If you need more complicated logic for a case, you can have a code block enclosed in curly braces, where the special
yield statement works like a sort of local return statement.
This form is not really important for this course, but you may encounter it in newer Java code.
Construction 8. Larger types and the default case for switch
[comp1110-78] - Fabian Muehlboeck
Construction 8. Larger types and the default case for switch
[comp1110-78]- Fabian Muehlboeck
The switch statements/expressions do not just work on enum values - in fact, they can distinguish between values of a wide variety of types.
Modern Java uses them to implement a kind of pattern-matching you might be used to from Haskell (but do not worry if you are not - if at all, we will only see that towards the end of this course).
You can also use them on strings or integers.
But those have many possible values - you don't really want to be writing cases for each and every one of them!
Any switch statement or expression can contain a default case for all other values not captures by previous cases.
In addition, individual cases can capture multiple values, like so:
And similarly, you can do the same for Strings:
The main difference here is that the latter works for all kinds of Strings, so you need to be careful about what your catch-all default case expresses. Here, the string "December" would return false, too!