|
| 1 | +--- |
| 2 | +id: lang.classes.enums |
| 3 | +title: Enums |
| 4 | +slug: learn/classes-objects/enums |
| 5 | +type: tutorial-group |
| 6 | +group: classes-and-objects |
| 7 | +layout: learn/tutorial-group.html |
| 8 | +subheader_select: tutorials |
| 9 | +main_css_id: learn |
| 10 | +toc: |
| 11 | +- What are enums? {intro} |
| 12 | +- Accessing, evaluating, and comparing enums {accessing} |
| 13 | +- Adding members to enums {members} |
| 14 | +- Special methods {functionality} |
| 15 | +- Using enums as singletons {singletons} |
| 16 | +- Abstract methods in enums {abstract} |
| 17 | +- Precautions {precautions} |
| 18 | +- Conclusion {conclusion} |
| 19 | +description: "Working with enums." |
| 20 | +last_update: 2023-09-29 |
| 21 | +author: ["DanielSchmid"] |
| 22 | +--- |
| 23 | +<a id="intro"> </a> |
| 24 | +## What are enums? |
| 25 | + |
| 26 | +Enums are classes where all instances are known to the compiler. |
| 27 | +They are used for creating types that can only have few possible values. |
| 28 | + |
| 29 | +Enums can be created similar to classes but use the `enum` keyword instead of `class`. |
| 30 | +In the body, there is a list of instances of the enum called enum constants which are seperated by `,`. |
| 31 | +No instances of the enum can be created outside of enum constants. |
| 32 | + |
| 33 | +```java |
| 34 | +public enum DayOfWeek { |
| 35 | + // enum constant are listed here: |
| 36 | + MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY |
| 37 | +} |
| 38 | +``` |
| 39 | + |
| 40 | +All enums implicitly extend [`java.lang.Enum`](javadoc:Enum) and cannot have any subclasses. |
| 41 | + |
| 42 | +<a id="accessing"> </a> |
| 43 | +## Accessing, evaluating, and comparing enums |
| 44 | + |
| 45 | +The values of an enum can be used as constants. |
| 46 | +In order to check whether two instances of an enum are the same, the `==` operator can be used. |
| 47 | +```java |
| 48 | +DayOfWeek weekStart = DayOfWeek.MONDAY; |
| 49 | + |
| 50 | +if (weekStart == DayOfWeek.MONDAY) { |
| 51 | + System.out.println("The week starts on Monday."); |
| 52 | +} |
| 53 | +``` |
| 54 | + |
| 55 | +It is also possible to use `switch` for performing actions depending on the value of the enum. |
| 56 | + |
| 57 | +```java |
| 58 | +DayOfWeek someDay = DayOfWeek.FRIDAY; |
| 59 | + |
| 60 | +switch (someDay) { |
| 61 | + case MONDAY -> |
| 62 | + System.out.println("The week just started."); |
| 63 | + case TUESDAY, WEDNESDAY, THURSDAY -> |
| 64 | + System.out.println("We are somewhere in the middle of the week."); |
| 65 | + case FRIDAY -> |
| 66 | + System.out.println("The weekend is near."); |
| 67 | + case SATURDAY, SUNDAY -> |
| 68 | + System.out.println("Weekend"); |
| 69 | + default -> |
| 70 | + throw new AssertionError("Should not happen"); |
| 71 | +} |
| 72 | +``` |
| 73 | + |
| 74 | +With [Switch Expressions](id:lang.classes-objects.switch-expression), |
| 75 | +the compiler can check whether all values of the enum are handled. |
| 76 | +If any possible value is missing in a switch expression, there will be a compiler error. |
| 77 | +This is referred to as Exhaustiveness and can also be achieved with regular classes |
| 78 | +through [Sealed Classes](https://openjdk.org/jeps/409). |
| 79 | + |
| 80 | +```java |
| 81 | +DayOfWeek someDay = DayOfWeek.FRIDAY; |
| 82 | + |
| 83 | +String text = switch (someDay) { |
| 84 | + case MONDAY -> "The week just started."; |
| 85 | + case TUESDAY, WEDNESDAY, THURSDAY -> "We are somewhere in the middle of the week."; |
| 86 | + case FRIDAY -> "The weekend is near."; |
| 87 | + case SATURDAY, SUNDAY -> "Weekend"; |
| 88 | +}; |
| 89 | + |
| 90 | +System.out.println(text); |
| 91 | +``` |
| 92 | + |
| 93 | +<a id="members"> </a> |
| 94 | +## Adding members to enums |
| 95 | + |
| 96 | +Just like classes, enums can have constructors, methods and fields. |
| 97 | +In order to add these, it is necessary to add a `;` after the list of enum constants. |
| 98 | +Arguments to the constructor are passed in parenthesis after the declaration of the enum constant. |
| 99 | + |
| 100 | +```java |
| 101 | +public enum DayOfWeek { |
| 102 | + MONDAY("MON"), TUESDAY("TUE"), WEDNESDAY("WED"), THURSDAY("THU"), FRIDAY("FRI"), SATURDAY("SAT"), SUNDAY("SUN"); |
| 103 | + |
| 104 | + private final String abbreviation; |
| 105 | + |
| 106 | + DayOfWeek(String abbreviation) { |
| 107 | + this.abbreviation = abbreviation; |
| 108 | + } |
| 109 | + |
| 110 | + public String getAbbreviation() { |
| 111 | + return abbreviation; |
| 112 | + } |
| 113 | +} |
| 114 | +``` |
| 115 | + |
| 116 | +<a id="functionality"> </a> |
| 117 | +## Special methods |
| 118 | + |
| 119 | +All enums have a few methods that are added implicitly. |
| 120 | + |
| 121 | +For example, the method `name()` is present in all enum instances and can be used to get the name of the enum constant. |
| 122 | +Similarly, a method named `ordinal()` returns the position of the enum constant in the declaration. |
| 123 | +```java |
| 124 | +System.out.println(DayOfWeek.MONDAY.name()); // prints "MONDAY" |
| 125 | +System.out.println(DayOfWeek.MONDAY.ordinal()); // prints "0" because MONDAY is the first constant in the DayOfWeek enum |
| 126 | +``` |
| 127 | + |
| 128 | +Aside from instance methods, there are also static methods added to all enums. |
| 129 | +The method `values()` returns an array containing all instances of the enum and the method `valueOf(String)` can be used to get a specific instance by its name. |
| 130 | +```java |
| 131 | +DayOfWeek[] days = DayOfWeek.values(); // all days of the week |
| 132 | +DayOfWeek monday = DayOfWeek.valueOf("MONDAY"); |
| 133 | +``` |
| 134 | + |
| 135 | +Furthermore, enums implement the interface [`Comparable`](javadoc:Comparable). |
| 136 | +By default, enums are ordered according to their ordinal number |
| 137 | +i.e. in the order of occurrence of the enum constant. |
| 138 | +This allows for comparing instances of enums as well as sorting or searching. |
| 139 | + |
| 140 | +```java |
| 141 | +public void compareDayOfWeek(DayOfWeek dayOfWeek){ |
| 142 | + int comparison = dayOfWeek.compareTo(DayOfWeek.WEDNESDAY); |
| 143 | + if ( comparison < 0) { |
| 144 | + System.out.println("It's before the middle of the work week."); |
| 145 | + } else if(comparison > 0){ |
| 146 | + System.out.println("It's after the middle of the work week."); |
| 147 | + } else { |
| 148 | + System.out.println("It's the middle of the work week."); |
| 149 | + } |
| 150 | +} |
| 151 | +``` |
| 152 | + |
| 153 | +```java |
| 154 | +List<DayOfWeek> days = new ArrayList<>(List.of(DayOfWeek.FRIDAY, DayOfWeek.TUESDAY, DayOfWeek.SATURDAY)); |
| 155 | +Collections.sort(days); |
| 156 | +``` |
| 157 | + |
| 158 | + |
| 159 | +<a id="singletons"> </a> |
| 160 | +## Using enums as singletons |
| 161 | + |
| 162 | +Since enums can only have a specific number of instances, it is possible to create a singleton by creating an enum with only a single enum constant. |
| 163 | +```java |
| 164 | +public enum SomeSingleton { |
| 165 | + INSTANCE; |
| 166 | + //fields, methods, etc. |
| 167 | +} |
| 168 | +``` |
| 169 | + |
| 170 | +<a id="abstract"> </a> |
| 171 | +## Abstract methods in enums |
| 172 | + |
| 173 | +Even though enums cannot be extended, they can still have `abstract` methods. In that case, an implementation must be present in each enum constant. |
| 174 | +```java |
| 175 | +enum MyEnum { |
| 176 | + A() { |
| 177 | + @Override |
| 178 | + void doSomething() { |
| 179 | + System.out.println("a"); |
| 180 | + } |
| 181 | + }, |
| 182 | + B() { |
| 183 | + @Override |
| 184 | + void doSomething() { |
| 185 | + System.out.println("b"); |
| 186 | + } |
| 187 | + }; |
| 188 | + |
| 189 | + abstract void doSomething(); |
| 190 | +} |
| 191 | +``` |
| 192 | + |
| 193 | +<a id="changing-instances"> </a> |
| 194 | +## Precautions |
| 195 | + |
| 196 | +Care should be taken when using enums where the number (or names) of instances is subject to change. |
| 197 | +Whenever enum constants are changed, other code expecting the old version of the enum might not work as expected. |
| 198 | +This may manifest in compilation errors (e.g. when referencing a removed enum constant), |
| 199 | +runtime errors (e.g. if there is a `default` case even though the new enum constant should be handled separately) |
| 200 | +or other inconsistencies (e.g. if the value of the enum was saved to a file which is then read and expecting that value to still exist). |
| 201 | + |
| 202 | +When changing enum constants, it is recommended to review all code using the enum. |
| 203 | +This is especially important in cases where the enum is also used by other people's code. |
| 204 | + |
| 205 | +Furthermore, it might be worth considering to use other options |
| 206 | +in case of many instances since listing a lot of instances at a single location in code can be inflexible. |
| 207 | +For example, it may be better to use a configuration file for listing all instances |
| 208 | +and reading these configuration files in the program in cases like this. |
| 209 | + |
| 210 | +<a id="conclusion"> </a> |
| 211 | +## Conclusion |
| 212 | + |
| 213 | +Enums provide a simple and safe way of representing a fixed set of constants while keeping most of the flexibilities of classes. They are a special type of class that can be used to write code that is elegant, readable, and maintainable, and work well with other newer modern features like [Switch Expressions](id:lang.classes-objects.switch-expression). Another special class is the Record class introduced in Java 19. Visit our [Records tutorial](id:lang.records) to learn more. |
| 214 | + |
| 215 | +To learn more about enums, visit the [`java.lang.Enum`](javadoc:Enum) javadoc. |
0 commit comments