SlideShare a Scribd company logo
EFFECTIVE
JAVA
Roshan Deniyage
Axiohelix Co. Ltd, Japan
15/11/2010
Enums and Annotations
Use enums instead of int constants
 In java 1.5 language add new class called enum type
 An enumerated type is a type whose legal value consists of fixed set of constants. As
examples,
 Planets in the solar system
 Suits in the deck of playing card
 Before enum types were added to the language the common pattern was group of
named int constants
// The int enum pattern
 public static final int APPLE_FUJI = 0;
 public static final int APPLE_PIPPIN = 1;
 public static final int APPLE_GRANNY_SMITH = 2;
 public static final int ORANGE_NAVEL = 0;
 public static final int ORANGE_TEMPLE = 1;
 public static final int ORANGE_BLOOD = 2;
Use enums instead of int constants
Use enums instead of int constants
Disadvantages of this technique
 It provides nothing in the way of type safety and little in the way of convenience.
 The compiler won’t complain if you pass an apple to a method that expects an
orange.
 Each apple constant is prefixed with APPLE_ and the name of each orange constant
is prefixed with ORANGE_. This is because Java doesn’t provide namespaces for int
enum groups.
 Int enums are compile time constants, they are compiled into the clients that use
them, if the int associated with an enum constant is changed, its client must be
recompiled, If not there behavior will be undefined.
 There is no easy way to translate int enum constant into printable strings.
 There is no reliable way to iterate over all the enum constant in a group.
Java 1.5’s new feature
Example enum declaration
public enum Apple {FUJI, PIPPIN, GRANNY_SMITH}
public enum Orange {NAVEL, TEMPLE, BLOOD}
• Java’s enum types classes that exports one instance for each enumeration constant via
a public static final field.
• Enum types are effectively final and have no accessible constructors. (They are a
generalization of singletons)
• Enums are by their nature immutable, so all fields should be final (if there are).
Advantages of using enum
• Enum provides compile time type safety.
• Enum types with identically named constants coexist peacefully.
(because each type has its own namespace)
• Can add or reorder constants in an enum type without recompiling its clients .
(because the fields that export the constants provide a layer of insulation between an
enum type and its clients)
• Can translate enums into printable strings.
(by calling their toString method)
• Enum types let you add arbitrary methods and fields and implement arbitrary
interfaces.
(look at the example below)
Advantages of using enum
// Enum type with data and behavior
public enum Planet {
MERCURY(3.302e+23, 2.439e6),
VENUS (4.869e+24, 6.052e6),
EARTH (5.975e+24, 6.378e6),
MARS (6.419e+23, 3.393e6),
JUPITER(1.899e+27, 7.149e7),
SATURN (5.685e+26, 6.027e7),
URANUS (8.683e+25, 2.556e7),
NEPTUNE(1.024e+26, 2.477e7);
private final double mass; // In kilograms
private final double radius; // In meters
private final double surfaceGravity; // In m / s^2
// Universal gravitational constant in m^3 / kg s^2
private static final double G = 6.67300E-11;
// Constructor
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
surfaceGravity = G * mass / (radius * radius);
}
public double mass() { return mass; }
public double radius() { return radius; }
public double surfaceGravity() { return surfaceGravity; }
public double surfaceWeight(double mass) {
return mass * surfaceGravity; // F = ma
}
}
public class WeightTable {
public static void main(String[] args) {
double earthWeight = Double.parseDouble(args[0]);
double mass = earthWeight / Planet.EARTH.surfaceGravity();
for (Planet p : Planet.values())
System.out.printf("Weight on %s is %f%n",
p, p.surfaceWeight(mass));
}
}
Client program that uses the above enum
Weight on MERCURY is 66.133672
Weight on VENUS is 158.383926
Weight on EARTH is 175.000000
Weight on MARS is 66.430699
Weight on JUPITER is 442.693902
Weight on SATURN is 186.464970
Weight on URANUS is 158.349709
Weight on NEPTUNE is 198.846116
Program output
Rules associated declaring enum
• Unless you have a compelling reason to expose an enum method to its clients, declare it
private or, if need be, package-private.
• If an enum is generally useful, it should be a top-level class. if its use is tied to a
specific top-level class, it should be a member class of that top-level class.
** Sometimes you need to associate fundamentally different behavior with each constant.
Example
Suppose you are writing an enum type to represent the operations on a basic
four-function calculator, and you want to provide a method to perform the arithmetic
operation represented by each constant
First way
- Switch on the value of the enum
public enum Operation {
PLUS, MINUS, TIMES, DIVIDE;
// Do the arithmetic op represented by this constant
double apply(double x, double y) {
switch(this) {
case PLUS: return x + y;
case MINUS: return x - y;
case TIMES: return x * y;
case DIVIDE: return x / y;
}
throw new AssertionError ("Unknown op: " + this);
}
}
Drawback of this method
• It won’t compile without the throw statement because the end of the method is
technically reachable, even though it will never be reached.
• If you add a new enum constant but forget to add a corresponding case to the switch, the
enum will still compile, but it will fail at runtime when you try to apply the new operation
Second way (Constant specific method implementation)
// Enum type with constant-specific method implementations
public enum Operation {
PLUS { double apply(double x, double y){return x + y;} },
MINUS { double apply(double x, double y){return x - y;} },
TIMES { double apply(double x, double y){return x * y;} },
DIVIDE { double apply(double x, double y){return x / y;} };
abstract double apply(double x, double y);
}
Example
// Enum type with constant-specific class bodies and data
public enum Operation {
PLUS("+") {
double apply(double x, double y) { return x + y; }
},
MINUS("-") {
double apply(double x, double y) { return x - y; }
},
TIMES("*") {
double apply(double x, double y) { return x * y; }
},
DIVIDE("/") {
double apply(double x, double y) { return x / y; }
};
private final String symbol;
Operation(String symbol) { this.symbol = symbol; }
@Override public String toString() { return symbol; }
abstract double apply(double x, double y);
}
Constant-specific method implementations can be combined with constant specific data.
In some cases, overriding toString in an enum is very useful
Demonstration Program
public static void main(String[] args) {
double x = Double.parseDouble(args[0]);
double y = Double.parseDouble(args[1]);
for (Operation op : Operation.values()) {
System.out.printf("%f %s %f = %f%n“, x, op, y, op.apply(x, y));
}
}
Output
2.000000 + 4.000000 = 6.000000
2.000000 - 4.000000 = -2.000000
2.000000 * 4.000000 = 8.000000
2.000000 / 4.000000 = 0.500000
Disadvantages of Constant Specific Method Implementation
• They make it harder to share code among enum constants
Example (problem)
Consider an enum representing the days of the week in a payroll package. This
enum has a method that calculates a worker’s pay for that day given the worker’s
base salary (per hour) and the number of hours worked on that day. On the five
weekdays, any time worked in excess of a normal shift generates overtime pay; on
the two weekend days, all work generates overtime pay
Solution
First way (using switch statement)
// Enum that switches on its value to share code - questionable
enum PayrollDay {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY,SATURDAY, SUNDAY;
private static final int HOURS_PER_SHIFT = 8;
double pay(double hoursWorked, double payRate) {
double basePay = hoursWorked * payRate;
double overtimePay; // Calculate overtime pay
switch(this) {
case SATURDAY: case SUNDAY:
overtimePay = hoursWorked * payRate / 2;
default: // Weekdays
overtimePay = hoursWorked <= HOURS_PER_SHIFT ?
0 : (hoursWorked - HOURS_PER_SHIFT) * payRate / 2;
break;
}
return basePay + overtimePay;
}
}
Second way (constant-specific method implementations)
Disadvantages
- Would have to duplicate the overtime pay computation for each constant.
- Or move the computation into two helper methods (one for weekdays and one for
weekend days) and invoke the appropriate helper method from each constant.
- Or replacing the abstract overtimePay method on PayrollDay with a concrete method that
performs the overtime calculation for weekdays.
Third way
Move the overtime pay computation into a private nested enum, and to pass an
instance of this strategy enum to the constructor for the PayrollDay enum
- This method is more safer and more flexible
// The strategy enum pattern
enum PayrollDay {
MONDAY(PayType.WEEKDAY),
TUESDAY(PayType.WEEKDAY),
WEDNESDAY(PayType.WEEKDAY),
THURSDAY(PayType.WEEKDAY),
FRIDAY(PayType.WEEKDAY),
SATURDAY(PayType.WEEKEND),
SUNDAY(PayType.WEEKEND);
private final PayType payType;
PayrollDay(PayType payType) { this.payType = payType; }
double pay(double hoursWorked, double payRate) {
return payType.pay(hoursWorked, payRate);
}
// The strategy enum type
private enum PayType {
WEEKDAY {
double overtimePay(double hours, double payRate) {
return hours <= HOURS_PER_SHIFT ? 0 :
(hours - HOURS_PER_SHIFT) * payRate / 2;
}
},
WEEKEND {
double overtimePay(double hours, double payRate) {
return hours * payRate / 2;
}
};
private static final int HOURS_PER_SHIFT = 8;
abstract double overtimePay(double hrs, double payRate);
double pay(double hoursWorked, double payRate) {
double basePay = hoursWorked * payRate;
return basePay + overtimePay(hoursWorked, payRate);
}
}
}
Exceptional case
- Switches on enums are good for augmenting external enum types with constant-specific
behavior.
Example
// Switch on an enum to simulate a missing method
public static Operation inverse(Operation op) {
switch(op) {
case PLUS: return Operation.MINUS;
case MINUS: return Operation.PLUS;
case TIMES: return Operation.DIVIDE;
case DIVIDE: return Operation.TIMES;
default: throw new AssertionError("Unknown op: " + op);
}
}
- There is a performance disadvantage of enums over int constants
(space and time cost to load and initialize enum types)
Disadvantages of enum

More Related Content

PDF
itft-Decision making and branching in java
PPT
Arrays
PPTX
C# Asynchronous delegates
PDF
Constants, Variables and Data Types in Java
PPTX
Multithreading in java
PPTX
Classes objects in java
PPTX
I/O Streams
PPTX
Flow Control.pptx
itft-Decision making and branching in java
Arrays
C# Asynchronous delegates
Constants, Variables and Data Types in Java
Multithreading in java
Classes objects in java
I/O Streams
Flow Control.pptx

What's hot (20)

PPTX
Tree traversal techniques
PPTX
Java exception handling
PPS
Wrapper class
PPTX
Type casting
PPTX
Functions in c language
PDF
ITFT-Constants, variables and data types in java
PPTX
File in C language
PDF
Java I/o streams
PPTX
Exception Handling in C#
PPT
Binary tree
PDF
Java threads
PPT
Exception Handling in JAVA
PPTX
Pointer in c
PPTX
Exception handling c++
PPT
Strings
PPTX
Object oriented programming with python
PPTX
PPTX
PPTX
pipeline in computer architecture design
PPTX
Programming in c Arrays
Tree traversal techniques
Java exception handling
Wrapper class
Type casting
Functions in c language
ITFT-Constants, variables and data types in java
File in C language
Java I/o streams
Exception Handling in C#
Binary tree
Java threads
Exception Handling in JAVA
Pointer in c
Exception handling c++
Strings
Object oriented programming with python
pipeline in computer architecture design
Programming in c Arrays
Ad

Viewers also liked (9)

PPTX
Effective Java - Chapter 3: Methods Common to All Objects
PPTX
Effective Java - Chapter 2: Creating and Destroying Objects
PDF
Effective java 1 and 2
PPTX
Effective Java - Chapter 4: Classes and Interfaces
PPTX
The Go Programing Language 1
PPT
Effective Java - Generics
PDF
Effective java
PPTX
Effective java
PPTX
Effective Java
Effective Java - Chapter 3: Methods Common to All Objects
Effective Java - Chapter 2: Creating and Destroying Objects
Effective java 1 and 2
Effective Java - Chapter 4: Classes and Interfaces
The Go Programing Language 1
Effective Java - Generics
Effective java
Effective java
Effective Java
Ad

Similar to Effective Java - Enum and Annotations (20)

PDF
Functional Programming in Java 8
PPT
Unit 1: Primitive Types - Variables and Datatypes
PPTX
PPT
Jdk1.5 Features
PPT
Chapter 7 - Defining Your Own Classes - Part II
PPT
Java căn bản - Chapter7
PPT
MODULE 1 EnumerationSSP. for adavanced lecture
PDF
Storage classes arrays & functions in C Language
PPTX
A Details Overview How to Use Typescript Generic Type
PPT
06slide.ppt
PDF
Java concepts and questions
PDF
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
PPTX
JAVA METHOD AND FUNCTION DIVIDE AND SHORT.pptx
PPTX
C concepts and programming examples for beginners
DOCX
Methods in Java
PPTX
Polymorphism in java
PPT
Md06 advance class features
PDF
PROGRAM 2 – Fraction Class Problem For this programming as.pdf
PDF
Let's make a contract: the art of designing a Java API
PPT
05 junit
Functional Programming in Java 8
Unit 1: Primitive Types - Variables and Datatypes
Jdk1.5 Features
Chapter 7 - Defining Your Own Classes - Part II
Java căn bản - Chapter7
MODULE 1 EnumerationSSP. for adavanced lecture
Storage classes arrays & functions in C Language
A Details Overview How to Use Typescript Generic Type
06slide.ppt
Java concepts and questions
documents.pub_new-features-in-java-8-it-jpoialjavanaitedwien15java8pdf-java-8...
JAVA METHOD AND FUNCTION DIVIDE AND SHORT.pptx
C concepts and programming examples for beginners
Methods in Java
Polymorphism in java
Md06 advance class features
PROGRAM 2 – Fraction Class Problem For this programming as.pdf
Let's make a contract: the art of designing a Java API
05 junit

Recently uploaded (20)

PDF
Encapsulation theory and applications.pdf
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PPTX
1. Introduction to Computer Programming.pptx
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PPTX
Machine Learning_overview_presentation.pptx
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Empathic Computing: Creating Shared Understanding
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PPTX
MYSQL Presentation for SQL database connectivity
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PPTX
SOPHOS-XG Firewall Administrator PPT.pptx
PPTX
Big Data Technologies - Introduction.pptx
PDF
Spectral efficient network and resource selection model in 5G networks
Encapsulation theory and applications.pdf
gpt5_lecture_notes_comprehensive_20250812015547.pdf
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Dropbox Q2 2025 Financial Results & Investor Presentation
Digital-Transformation-Roadmap-for-Companies.pptx
20250228 LYD VKU AI Blended-Learning.pptx
1. Introduction to Computer Programming.pptx
Network Security Unit 5.pdf for BCA BBA.
Per capita expenditure prediction using model stacking based on satellite ima...
Machine Learning_overview_presentation.pptx
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Building Integrated photovoltaic BIPV_UPV.pdf
Empathic Computing: Creating Shared Understanding
Mobile App Security Testing_ A Comprehensive Guide.pdf
MYSQL Presentation for SQL database connectivity
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
“AI and Expert System Decision Support & Business Intelligence Systems”
SOPHOS-XG Firewall Administrator PPT.pptx
Big Data Technologies - Introduction.pptx
Spectral efficient network and resource selection model in 5G networks

Effective Java - Enum and Annotations

  • 1. EFFECTIVE JAVA Roshan Deniyage Axiohelix Co. Ltd, Japan 15/11/2010 Enums and Annotations Use enums instead of int constants
  • 2.  In java 1.5 language add new class called enum type  An enumerated type is a type whose legal value consists of fixed set of constants. As examples,  Planets in the solar system  Suits in the deck of playing card  Before enum types were added to the language the common pattern was group of named int constants // The int enum pattern  public static final int APPLE_FUJI = 0;  public static final int APPLE_PIPPIN = 1;  public static final int APPLE_GRANNY_SMITH = 2;  public static final int ORANGE_NAVEL = 0;  public static final int ORANGE_TEMPLE = 1;  public static final int ORANGE_BLOOD = 2; Use enums instead of int constants
  • 3. Use enums instead of int constants Disadvantages of this technique  It provides nothing in the way of type safety and little in the way of convenience.  The compiler won’t complain if you pass an apple to a method that expects an orange.  Each apple constant is prefixed with APPLE_ and the name of each orange constant is prefixed with ORANGE_. This is because Java doesn’t provide namespaces for int enum groups.  Int enums are compile time constants, they are compiled into the clients that use them, if the int associated with an enum constant is changed, its client must be recompiled, If not there behavior will be undefined.  There is no easy way to translate int enum constant into printable strings.  There is no reliable way to iterate over all the enum constant in a group.
  • 4. Java 1.5’s new feature Example enum declaration public enum Apple {FUJI, PIPPIN, GRANNY_SMITH} public enum Orange {NAVEL, TEMPLE, BLOOD} • Java’s enum types classes that exports one instance for each enumeration constant via a public static final field. • Enum types are effectively final and have no accessible constructors. (They are a generalization of singletons) • Enums are by their nature immutable, so all fields should be final (if there are).
  • 5. Advantages of using enum • Enum provides compile time type safety. • Enum types with identically named constants coexist peacefully. (because each type has its own namespace) • Can add or reorder constants in an enum type without recompiling its clients . (because the fields that export the constants provide a layer of insulation between an enum type and its clients) • Can translate enums into printable strings. (by calling their toString method) • Enum types let you add arbitrary methods and fields and implement arbitrary interfaces. (look at the example below)
  • 6. Advantages of using enum // Enum type with data and behavior public enum Planet { MERCURY(3.302e+23, 2.439e6), VENUS (4.869e+24, 6.052e6), EARTH (5.975e+24, 6.378e6), MARS (6.419e+23, 3.393e6), JUPITER(1.899e+27, 7.149e7), SATURN (5.685e+26, 6.027e7), URANUS (8.683e+25, 2.556e7), NEPTUNE(1.024e+26, 2.477e7); private final double mass; // In kilograms private final double radius; // In meters private final double surfaceGravity; // In m / s^2 // Universal gravitational constant in m^3 / kg s^2 private static final double G = 6.67300E-11; // Constructor Planet(double mass, double radius) { this.mass = mass; this.radius = radius; surfaceGravity = G * mass / (radius * radius); } public double mass() { return mass; } public double radius() { return radius; } public double surfaceGravity() { return surfaceGravity; } public double surfaceWeight(double mass) { return mass * surfaceGravity; // F = ma } }
  • 7. public class WeightTable { public static void main(String[] args) { double earthWeight = Double.parseDouble(args[0]); double mass = earthWeight / Planet.EARTH.surfaceGravity(); for (Planet p : Planet.values()) System.out.printf("Weight on %s is %f%n", p, p.surfaceWeight(mass)); } } Client program that uses the above enum Weight on MERCURY is 66.133672 Weight on VENUS is 158.383926 Weight on EARTH is 175.000000 Weight on MARS is 66.430699 Weight on JUPITER is 442.693902 Weight on SATURN is 186.464970 Weight on URANUS is 158.349709 Weight on NEPTUNE is 198.846116 Program output
  • 8. Rules associated declaring enum • Unless you have a compelling reason to expose an enum method to its clients, declare it private or, if need be, package-private. • If an enum is generally useful, it should be a top-level class. if its use is tied to a specific top-level class, it should be a member class of that top-level class. ** Sometimes you need to associate fundamentally different behavior with each constant. Example Suppose you are writing an enum type to represent the operations on a basic four-function calculator, and you want to provide a method to perform the arithmetic operation represented by each constant
  • 9. First way - Switch on the value of the enum public enum Operation { PLUS, MINUS, TIMES, DIVIDE; // Do the arithmetic op represented by this constant double apply(double x, double y) { switch(this) { case PLUS: return x + y; case MINUS: return x - y; case TIMES: return x * y; case DIVIDE: return x / y; } throw new AssertionError ("Unknown op: " + this); } } Drawback of this method • It won’t compile without the throw statement because the end of the method is technically reachable, even though it will never be reached. • If you add a new enum constant but forget to add a corresponding case to the switch, the enum will still compile, but it will fail at runtime when you try to apply the new operation
  • 10. Second way (Constant specific method implementation) // Enum type with constant-specific method implementations public enum Operation { PLUS { double apply(double x, double y){return x + y;} }, MINUS { double apply(double x, double y){return x - y;} }, TIMES { double apply(double x, double y){return x * y;} }, DIVIDE { double apply(double x, double y){return x / y;} }; abstract double apply(double x, double y); }
  • 11. Example // Enum type with constant-specific class bodies and data public enum Operation { PLUS("+") { double apply(double x, double y) { return x + y; } }, MINUS("-") { double apply(double x, double y) { return x - y; } }, TIMES("*") { double apply(double x, double y) { return x * y; } }, DIVIDE("/") { double apply(double x, double y) { return x / y; } }; private final String symbol; Operation(String symbol) { this.symbol = symbol; } @Override public String toString() { return symbol; } abstract double apply(double x, double y); } Constant-specific method implementations can be combined with constant specific data.
  • 12. In some cases, overriding toString in an enum is very useful Demonstration Program public static void main(String[] args) { double x = Double.parseDouble(args[0]); double y = Double.parseDouble(args[1]); for (Operation op : Operation.values()) { System.out.printf("%f %s %f = %f%n“, x, op, y, op.apply(x, y)); } } Output 2.000000 + 4.000000 = 6.000000 2.000000 - 4.000000 = -2.000000 2.000000 * 4.000000 = 8.000000 2.000000 / 4.000000 = 0.500000
  • 13. Disadvantages of Constant Specific Method Implementation • They make it harder to share code among enum constants Example (problem) Consider an enum representing the days of the week in a payroll package. This enum has a method that calculates a worker’s pay for that day given the worker’s base salary (per hour) and the number of hours worked on that day. On the five weekdays, any time worked in excess of a normal shift generates overtime pay; on the two weekend days, all work generates overtime pay Solution First way (using switch statement) // Enum that switches on its value to share code - questionable enum PayrollDay { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY,SATURDAY, SUNDAY; private static final int HOURS_PER_SHIFT = 8; double pay(double hoursWorked, double payRate) { double basePay = hoursWorked * payRate; double overtimePay; // Calculate overtime pay switch(this) { case SATURDAY: case SUNDAY: overtimePay = hoursWorked * payRate / 2; default: // Weekdays overtimePay = hoursWorked <= HOURS_PER_SHIFT ? 0 : (hoursWorked - HOURS_PER_SHIFT) * payRate / 2; break; } return basePay + overtimePay; } }
  • 14. Second way (constant-specific method implementations) Disadvantages - Would have to duplicate the overtime pay computation for each constant. - Or move the computation into two helper methods (one for weekdays and one for weekend days) and invoke the appropriate helper method from each constant. - Or replacing the abstract overtimePay method on PayrollDay with a concrete method that performs the overtime calculation for weekdays. Third way Move the overtime pay computation into a private nested enum, and to pass an instance of this strategy enum to the constructor for the PayrollDay enum - This method is more safer and more flexible
  • 15. // The strategy enum pattern enum PayrollDay { MONDAY(PayType.WEEKDAY), TUESDAY(PayType.WEEKDAY), WEDNESDAY(PayType.WEEKDAY), THURSDAY(PayType.WEEKDAY), FRIDAY(PayType.WEEKDAY), SATURDAY(PayType.WEEKEND), SUNDAY(PayType.WEEKEND); private final PayType payType; PayrollDay(PayType payType) { this.payType = payType; } double pay(double hoursWorked, double payRate) { return payType.pay(hoursWorked, payRate); } // The strategy enum type private enum PayType { WEEKDAY { double overtimePay(double hours, double payRate) { return hours <= HOURS_PER_SHIFT ? 0 : (hours - HOURS_PER_SHIFT) * payRate / 2; } }, WEEKEND { double overtimePay(double hours, double payRate) { return hours * payRate / 2; } }; private static final int HOURS_PER_SHIFT = 8; abstract double overtimePay(double hrs, double payRate); double pay(double hoursWorked, double payRate) { double basePay = hoursWorked * payRate; return basePay + overtimePay(hoursWorked, payRate); } } }
  • 16. Exceptional case - Switches on enums are good for augmenting external enum types with constant-specific behavior. Example // Switch on an enum to simulate a missing method public static Operation inverse(Operation op) { switch(op) { case PLUS: return Operation.MINUS; case MINUS: return Operation.PLUS; case TIMES: return Operation.DIVIDE; case DIVIDE: return Operation.TIMES; default: throw new AssertionError("Unknown op: " + op); } } - There is a performance disadvantage of enums over int constants (space and time cost to load and initialize enum types) Disadvantages of enum