Java 5 introduces several new features that offer significant improvements over older Java technology. We consider the new enum construct, which provides language support for enumerated types. Prior to Java 5, programmers needed to employ various patterns (e.g., the weak enum pattern) to compensate for the absence of enumerated types in Java. Unfortunately, these compensation patterns lack several highly-desirable properties of the enum construct, most notably, type safety. I present a novel fully-automated approach for transforming legacy Java code to use the new enumeration construct. This semantics-preserving approach increases type safety, produces code that is easier to comprehend, removes unnecessary complexity, and eliminates brittleness problems due to separate compilation. At the core of the proposed approach is an interprocedural type inferencing algorithm which tracks the flow of enumerated values. The algorithm was implemented as an Eclipse plug-in and evaluated experimentally on 17 large Java benchmarks. Our results indicate that analysis cost is practical and the algorithm can successfully refactor a substantial number of fields to enumerated types. This work is a significant step towards providing automated tool support for migrating legacy Java software to modern Java technologies. I also discuss directions for future research in detail.
Poster on Automated Refactoring of Legacy Java Software to Default Methods
Future Endeavors in Automated Refactoring of Legacy Java Software to Enumerated Types
1. Future Endeavors in Automated
Refactoring of Legacy Java Software
to Enumerated Types*
Raffi Khatchadourian, Jason Sawin, and Atanas Rountev
PRESTO: Program Analyses and Software Tools Research
Group, Ohio State University
* Work supported in part by NSF
6. Motivation
• Software changes over
time:
• Requirements evolve
• Different platforms
(e.g., mobile devices)
• New framework
versions (e.g., XML vs.
annotation-based)
2
10. Motivation
Changing and/or maintaining large, complex software
systems can be non-trivial:
Tedious:May require changing many lines of
code.
Adding a
parameter to a
method
11. Motivation
Changing and/or maintaining large, complex software
systems can be non-trivial:
Tedious:May require changing many lines of
code.
Error-prone: Changes may be implemented
incorrectly.
12. Motivation
Changing and/or maintaining large, complex software
systems can be non-trivial:
Tedious:May require changing many lines of
code.
Error-prone: Changes may be implemented
incorrectly.
Removing a
method parameter may
alter overloading to
overriding
13. Motivation
Changing and/or maintaining large, complex software
systems can be non-trivial:
Tedious:May require changing many lines of
code.
Error-prone: Changes may be implemented
incorrectly.
Omission-
prone:
May opportunities to produce better
code.
14. Motivation
Changing and/or maintaining large, complex software
systems can be non-trivial:
Tedious:May require changing many lines of
code.
Error-prone: Changes may be implemented
incorrectly.
Omission-
prone:
May opportunities to produce better
code.
HashTable vs.
HashMap
15. Motivation
Changing and/or maintaining large, complex software
systems can be non-trivial:
Tedious:May require changing many lines of
code.
Error-prone: Changes may be implemented
incorrectly.
Omission-
prone:
May opportunities to produce better
code.
18. Solution?
• Approaches made to
provide
assistance in evolution
tasks.
• Typically in the form of
plug-ins to IDEs.
19. Solution?
• Approaches made to
provide
assistance in evolution
tasks.
• Typically in the form of
plug-ins to IDEs.
• Ease the burden of
software maintenance
and evolution.
20. Solution?
• Approaches made to
provide
assistance in evolution
tasks.
• Typically in the form of
plug-ins to IDEs.
• Ease the burden of
software maintenance
and evolution.
Restrict
workspace to only
displays elements
relevant to the
task
21. Solution?
• Approaches made to
provide
assistance in evolution
tasks.
• Typically in the form of
plug-ins to IDEs.
• Ease the burden of
software maintenance
and evolution.
Restrict
workspace to only
displays elements
relevant to the
task
Restructure
code while preserving
semantics (i.e.,
refactoring)
23. Introduction
•Java 5 introduced a rich set of new features such as
generics, metadata annotations, boxing/unboxing,
and type-safe enumerations.
24. Introduction
•Java 5 introduced a rich set of new features such as
generics, metadata annotations, boxing/unboxing,
and
•Highlight an automated semantics-preserving
approach for migrating legacy Java code to take
advantage of the new language enumerated type
constructs.
25. Introduction
•Java 5 introduced a rich set of new features such as
generics, metadata annotations, boxing/unboxing,
and
•Highlight an automated semantics-preserving
approach for migrating legacy Java code to take
advantage of the new language enumerated type
constructs.
•Present experimental results from research prototype
as an Eclipse IDE plug-in.
26. Introduction
•Java 5 introduced a rich set of new features such as
generics, metadata annotations, boxing/unboxing,
and
•Highlight an automated semantics-preserving
approach for migrating legacy Java code to take
advantage of the new language enumerated type
constructs.
•Present experimental results from research prototype
as an Eclipse IDE plug-in.
•In progress to be included with the standard
distribution of Eclipse.
27. Introduction
•Java 5 introduced a rich set of new features such as
generics, metadata annotations, boxing/unboxing,
and
•Highlight an automated semantics-preserving
approach for migrating legacy Java code to take
advantage of the new language enumerated type
constructs.
•Present experimental results from research prototype
as an Eclipse IDE plug-in.
•In progress to be included with the standard
distribution of Eclipse.
•Discuss directions for future work.
28. Motivating Example
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
29. Motivating Example
Weak Enum
Pattern
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
30. Motivating Example
Type Safety
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
31. Motivating Example
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
Manual
Enumeration
32. Motivating Example
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
Namespacing
33. Motivating Example
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
Brittle
34. Motivating Example
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
35. Motivating Example Revisited
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
36. Motivating Example Revisited
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
private static final int MAX_SPEED = 140;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
37. Motivating Example Revisited
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
private static final int MAX_SPEED = 140;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
38. Motivating Example Revisited
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
private static final int MAX_SPEED = 140;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
39. Motivating Example Revisited
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
private static final int MAX_SPEED = 140;
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
40. Motivating Example Revisited
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
private static final int MAX_SPEED = 140;
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
Language Enum
41. Motivating Example Revisited
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
private static final int MAX_SPEED = 140;
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
Type Safety
42. Motivating Example Revisited
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
private static final int MAX_SPEED = 140;
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
Singletons in
Natural Order
43. Motivating Example Revisited
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
private static final int MAX_SPEED = 140;
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
Prefixed
44. Motivating Example Revisited
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
private static final int MAX_SPEED = 140;
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
Supports
Separate
Compilation
45. Motivating Example Revisited
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
private static final int MAX_SPEED = 140;
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
class TrafficSignal {
public enum Color {RED,
YELLOW,
GREEN};
/* Current color of the traffic signal, initially red by default */
private Color color = Color.RED;
/* Accessor for the light’s current color */
public Color getColor() {return this.color;}}
class Automobile {
private enum Action {IDLE,
INCREASE_SPEED,
DECREASE_SPEED,
STOP};
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
class TrafficSignal {
public static final int RED = 0;
public static final int YELLOW = 1;
public static final int GREEN = 2;
/ Current color of the traffic signal, initially red by default /
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
46. Traffic Signal Client
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
this.currentAction &&
INCREASE_SPEED ||
tSpeed <= MAX_SPEED))
rmAction(reaction);}
rmAction(int action) {...}}
eger constants for enumerated types.
38 (reacti
39 this.c
40 this.
41
42 private void
(b) Im
Figure 1. Running example: a hypothetical drive-by-w
ch machinery. Third, the weak enum
ogrammer to manually enumerate the
ts, which increases the likelihood of
different enum constants may be unin-
he same internal value. Finally, the
rittle [?]: since the values are com-
at compile time they are inlined into
new constants are added in between
example, in which
by language enum
and Automobile.
ations of these ne
through compile-tim
between the named
ated values. It is als
is an Action, whic
47. Traffic Signal Client
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
this.currentAction &&
INCREASE_SPEED ||
tSpeed <= MAX_SPEED))
rmAction(reaction);}
rmAction(int action) {...}}
eger constants for enumerated types.
38 (reacti
39 this.c
40 this.
41
42 private void
(b) Im
Figure 1. Running example: a hypothetical drive-by-w
ch machinery. Third, the weak enum
ogrammer to manually enumerate the
ts, which increases the likelihood of
different enum constants may be unin-
he same internal value. Finally, the
rittle [?]: since the values are com-
at compile time they are inlined into
new constants are added in between
example, in which
by language enum
and Automobile.
ations of these ne
through compile-tim
between the named
ated values. It is als
is an Action, whic
48. Traffic Signal Client
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
this.currentAction &&
INCREASE_SPEED ||
tSpeed <= MAX_SPEED))
rmAction(reaction);}
rmAction(int action) {...}}
eger constants for enumerated types.
38 (reacti
39 this.c
40 this.
41
42 private void
(b) Im
Figure 1. Running example: a hypothetical drive-by-w
ch machinery. Third, the weak enum
ogrammer to manually enumerate the
ts, which increases the likelihood of
different enum constants may be unin-
he same internal value. Finally, the
rittle [?]: since the values are com-
at compile time they are inlined into
new constants are added in between
example, in which
by language enum
and Automobile.
ations of these ne
through compile-tim
between the named
ated values. It is als
is an Action, whic
49. Traffic Signal Client
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
this.currentAction &&
INCREASE_SPEED ||
tSpeed <= MAX_SPEED))
rmAction(reaction);}
rmAction(int action) {...}}
eger constants for enumerated types.
38 (reacti
39 this.c
40 this.
41
42 private void
(b) Im
Figure 1. Running example: a hypothetical drive-by-w
ch machinery. Third, the weak enum
ogrammer to manually enumerate the
ts, which increases the likelihood of
different enum constants may be unin-
he same internal value. Finally, the
rittle [?]: since the values are com-
at compile time they are inlined into
new constants are added in between
example, in which
by language enum
and Automobile.
ations of these ne
through compile-tim
between the named
ated values. It is als
is an Action, whic
50. Traffic Signal Client
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
this.currentAction &&
INCREASE_SPEED ||
tSpeed <= MAX_SPEED))
rmAction(reaction);}
rmAction(int action) {...}}
eger constants for enumerated types.
38 (reacti
39 this.c
40 this.
41
42 private void
(b) Im
Figure 1. Running example: a hypothetical drive-by-w
ch machinery. Third, the weak enum
ogrammer to manually enumerate the
ts, which increases the likelihood of
different enum constants may be unin-
he same internal value. Finally, the
rittle [?]: since the values are com-
at compile time they are inlined into
new constants are added in between
example, in which
by language enum
and Automobile.
ations of these ne
through compile-tim
between the named
ated values. It is als
is an Action, whic
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
Automobile
Action Enum
51. Traffic Signal Client
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
this.currentAction &&
INCREASE_SPEED ||
tSpeed <= MAX_SPEED))
rmAction(reaction);}
rmAction(int action) {...}}
eger constants for enumerated types.
38 (reacti
39 this.c
40 this.
41
42 private void
(b) Im
Figure 1. Running example: a hypothetical drive-by-w
ch machinery. Third, the weak enum
ogrammer to manually enumerate the
ts, which increases the likelihood of
different enum constants may be unin-
he same internal value. Finally, the
rittle [?]: since the values are com-
at compile time they are inlined into
new constants are added in between
example, in which
by language enum
and Automobile.
ations of these ne
through compile-tim
between the named
ated values. It is als
is an Action, whic
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
Named-
Constant
52. Traffic Signal Client
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
this.currentAction &&
INCREASE_SPEED ||
tSpeed <= MAX_SPEED))
rmAction(reaction);}
rmAction(int action) {...}}
eger constants for enumerated types.
38 (reacti
39 this.c
40 this.
41
42 private void
(b) Im
Figure 1. Running example: a hypothetical drive-by-w
ch machinery. Third, the weak enum
ogrammer to manually enumerate the
ts, which increases the likelihood of
different enum constants may be unin-
he same internal value. Finally, the
rittle [?]: since the values are com-
at compile time they are inlined into
new constants are added in between
example, in which
by language enum
and Automobile.
ations of these ne
through compile-tim
between the named
ated values. It is als
is an Action, whic
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
Promising...
53. Traffic Signal Client
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
this.currentAction &&
INCREASE_SPEED ||
tSpeed <= MAX_SPEED))
rmAction(reaction);}
rmAction(int action) {...}}
eger constants for enumerated types.
38 (reacti
39 this.c
40 this.
41
42 private void
(b) Im
Figure 1. Running example: a hypothetical drive-by-w
ch machinery. Third, the weak enum
ogrammer to manually enumerate the
ts, which increases the likelihood of
different enum constants may be unin-
he same internal value. Finally, the
rittle [?]: since the values are com-
at compile time they are inlined into
new constants are added in between
example, in which
by language enum
and Automobile.
ations of these ne
through compile-tim
between the named
ated values. It is als
is an Action, whic
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
Definitely not
enumerizable
54. Traffic Signal Client
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
this.currentAction &&
INCREASE_SPEED ||
tSpeed <= MAX_SPEED))
rmAction(reaction);}
rmAction(int action) {...}}
eger constants for enumerated types.
38 (reacti
39 this.c
40 this.
41
42 private void
(b) Im
Figure 1. Running example: a hypothetical drive-by-w
ch machinery. Third, the weak enum
ogrammer to manually enumerate the
ts, which increases the likelihood of
different enum constants may be unin-
he same internal value. Finally, the
rittle [?]: since the values are com-
at compile time they are inlined into
new constants are added in between
example, in which
by language enum
and Automobile.
ations of these ne
through compile-tim
between the named
ated values. It is als
is an Action, whic
55. Traffic Signal Client
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
this.currentAction &&
INCREASE_SPEED ||
tSpeed <= MAX_SPEED))
rmAction(reaction);}
rmAction(int action) {...}}
eger constants for enumerated types.
38 (reacti
39 this.c
40 this.
41
42 private void
(b) Im
Figure 1. Running example: a hypothetical drive-by-w
ch machinery. Third, the weak enum
ogrammer to manually enumerate the
ts, which increases the likelihood of
different enum constants may be unin-
he same internal value. Finally, the
rittle [?]: since the values are com-
at compile time they are inlined into
new constants are added in between
example, in which
by language enum
and Automobile.
ations of these ne
through compile-tim
between the named
ated values. It is als
is an Action, whic
56. Traffic Signal Client
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
this.currentAction &&
INCREASE_SPEED ||
tSpeed <= MAX_SPEED))
rmAction(reaction);}
rmAction(int action) {...}}
eger constants for enumerated types.
38 (reacti
39 this.c
40 this.
41
42 private void
(b) Im
Figure 1. Running example: a hypothetical drive-by-w
ch machinery. Third, the weak enum
ogrammer to manually enumerate the
ts, which increases the likelihood of
different enum constants may be unin-
he same internal value. Finally, the
rittle [?]: since the values are com-
at compile time they are inlined into
new constants are added in between
example, in which
by language enum
and Automobile.
ations of these ne
through compile-tim
between the named
ated values. It is als
is an Action, whic
57. / The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
Traffic Signal Client
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
this.currentAction &&
INCREASE_SPEED ||
tSpeed <= MAX_SPEED))
rmAction(reaction);}
rmAction(int action) {...}}
eger constants for enumerated types.
38 (reacti
39 this.c
40 this.
41
42 private void
(b) Im
Figure 1. Running example: a hypothetical drive-by-w
ch machinery. Third, the weak enum
ogrammer to manually enumerate the
ts, which increases the likelihood of
different enum constants may be unin-
he same internal value. Finally, the
rittle [?]: since the values are com-
at compile time they are inlined into
new constants are added in between
example, in which
by language enum
and Automobile.
ations of these ne
through compile-tim
between the named
ated values. It is als
is an Action, whic
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/* The action this automobile is currently performing, idle by default */
private Action currentAction = Action.IDLE;
/* The current speed of the automobile, initially 5 mph. */
private int currentSpeed = 5;
private Action react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return Action.STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return Action.INCREASE_SPEED;
else return Action.STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
Action reaction = this.react(aSignal);
58. Traffic Signal Client
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
this.currentAction &&
INCREASE_SPEED ||
tSpeed <= MAX_SPEED))
rmAction(reaction);}
rmAction(int action) {...}}
eger constants for enumerated types.
38 (reacti
39 this.c
40 this.
41
42 private void
(b) Im
Figure 1. Running example: a hypothetical drive-by-w
ch machinery. Third, the weak enum
ogrammer to manually enumerate the
ts, which increases the likelihood of
different enum constants may be unin-
he same internal value. Finally, the
rittle [?]: since the values are com-
at compile time they are inlined into
new constants are added in between
example, in which
by language enum
and Automobile.
ations of these ne
through compile-tim
between the named
ated values. It is als
is an Action, whic
/* The action this automobile is currently performing, idle by default */
private Action currentAction = Action.IDLE;
/* The current speed of the automobile, initially 5 mph. */
private int currentSpeed = 5;
private Action react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return Action.STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return Action.INCREASE_SPEED;
else return Action.STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
Action reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/* The action this automobile is currently performing, idle by default */
private Action currentAction = Action.IDLE;
/* The current speed of the automobile, initially 5 mph. */
private int currentSpeed = 5;
private Action react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return Action.STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return Action.INCREASE_SPEED;
else return Action.STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
Action reaction = this.react(aSignal);
59. Traffic Signal Client
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
this.currentAction &&
INCREASE_SPEED ||
tSpeed <= MAX_SPEED))
rmAction(reaction);}
rmAction(int action) {...}}
eger constants for enumerated types.
38 (reacti
39 this.c
40 this.
41
42 private void
(b) Im
Figure 1. Running example: a hypothetical drive-by-w
ch machinery. Third, the weak enum
ogrammer to manually enumerate the
ts, which increases the likelihood of
different enum constants may be unin-
he same internal value. Finally, the
rittle [?]: since the values are com-
at compile time they are inlined into
new constants are added in between
example, in which
by language enum
and Automobile.
ations of these ne
through compile-tim
between the named
ated values. It is als
is an Action, whic
/* The action this automobile is currently performing, idle by default */
private Action currentAction = Action.IDLE;
/* The current speed of the automobile, initially 5 mph. */
private int currentSpeed = 5;
private Action react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return Action.STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return Action.INCREASE_SPEED;
else return Action.STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
Action reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/* The action this automobile is currently performing, idle by default */
private Action currentAction = Action.IDLE;
/* The current speed of the automobile, initially 5 mph. */
private int currentSpeed = 5;
private Action react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return Action.STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return Action.INCREASE_SPEED;
else return Action.STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
Action reaction = this.react(aSignal);
/* The action this automobile is currently performing, idle by default */
private Action currentAction = Action.IDLE;
/* The current speed of the automobile, initially 5 mph. */
private int currentSpeed = 5;
private Action react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return Action.STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return Action.INCREASE_SPEED;
else return Action.STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
Action reaction = this.react(aSignal);
60. /* The action this automobile is currently performing, idle by default */
private Action currentAction = Action.IDLE;
/* The current speed of the automobile, initially 5 mph. */
private int currentSpeed = 5;
private Action react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return Action.STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return Action.INCREASE_SPEED;
else return Action.STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
Action reaction = this.react(aSignal);
Traffic Signal Client
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
this.currentAction &&
INCREASE_SPEED ||
tSpeed <= MAX_SPEED))
rmAction(reaction);}
rmAction(int action) {...}}
eger constants for enumerated types.
38 (reacti
39 this.c
40 this.
41
42 private void
(b) Im
Figure 1. Running example: a hypothetical drive-by-w
ch machinery. Third, the weak enum
ogrammer to manually enumerate the
ts, which increases the likelihood of
different enum constants may be unin-
he same internal value. Finally, the
rittle [?]: since the values are com-
at compile time they are inlined into
new constants are added in between
example, in which
by language enum
and Automobile.
ations of these ne
through compile-tim
between the named
ated values. It is als
is an Action, whic
/* The action this automobile is currently performing, idle by default */
private Action currentAction = Action.IDLE;
/* The current speed of the automobile, initially 5 mph. */
private int currentSpeed = 5;
private Action react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return Action.STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return Action.INCREASE_SPEED;
else return Action.STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
Action reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/* The action this automobile is currently performing, idle by default */
private Action currentAction = Action.IDLE;
/* The current speed of the automobile, initially 5 mph. */
private int currentSpeed = 5;
private Action react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return Action.STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return Action.INCREASE_SPEED;
else return Action.STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
Action reaction = this.react(aSignal);
/* The action this automobile is currently performing, idle by default */
private Action currentAction = Action.IDLE;
/* The current speed of the automobile, initially 5 mph. */
private int currentSpeed = 5;
private Action react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return Action.STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return Action.INCREASE_SPEED;
else return Action.STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
Action reaction = this.react(aSignal);
61. /* The action this automobile is currently performing, idle by default */
private Action currentAction = Action.IDLE;
/* The current speed of the automobile, initially 5 mph. */
private int currentSpeed = 5;
private Action react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return Action.STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return Action.INCREASE_SPEED;
else return Action.STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
Action reaction = this.react(aSignal);
Traffic Signal Client
private int color = RED;
/ Accessor for the light’s current color /
public int getColor() {return this.color;}}
class Automobile {
private static final int IDLE = 0;
private static final int INCREASE_SPEED = 1;
private static final int DECREASE_SPEED = 2;
private static final int STOP = 3;
private static final int MAX_SPEED = 140;
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
this.currentAction &&
INCREASE_SPEED ||
tSpeed <= MAX_SPEED))
rmAction(reaction);}
rmAction(int action) {...}}
eger constants for enumerated types.
38 (reacti
39 this.c
40 this.
41
42 private void
(b) Im
Figure 1. Running example: a hypothetical drive-by-w
ch machinery. Third, the weak enum
ogrammer to manually enumerate the
ts, which increases the likelihood of
different enum constants may be unin-
he same internal value. Finally, the
rittle [?]: since the values are com-
at compile time they are inlined into
new constants are added in between
example, in which
by language enum
and Automobile.
ations of these ne
through compile-tim
between the named
ated values. It is als
is an Action, whic
/* The action this automobile is currently performing, idle by default */
private Action currentAction = Action.IDLE;
/* The current speed of the automobile, initially 5 mph. */
private int currentSpeed = 5;
private Action react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return Action.STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return Action.INCREASE_SPEED;
else return Action.STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
Action reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/ The action this automobile is currently performing, idle by default /
private int currentAction = IDLE;
/ The current speed of the automobile, initially 5 mph. /
private int currentSpeed = 5;
private int react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return INCREASE_SPEED;
else return STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
int reaction = this.react(aSignal);
/* The action this automobile is currently performing, idle by default */
private Action currentAction = Action.IDLE;
/* The current speed of the automobile, initially 5 mph. */
private int currentSpeed = 5;
private Action react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return Action.STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return Action.INCREASE_SPEED;
else return Action.STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
Action reaction = this.react(aSignal);
/* The action this automobile is currently performing, idle by default */
private Action currentAction = Action.IDLE;
/* The current speed of the automobile, initially 5 mph. */
private int currentSpeed = 5;
private Action react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return Action.STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return Action.INCREASE_SPEED;
else return Action.STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
Action reaction = this.react(aSignal);
/* The action this automobile is currently performing, idle by default */
private Action currentAction = Action.IDLE;
/* The current speed of the automobile, initially 5 mph. */
private int currentSpeed = 5;
private Action react(TrafficSignal signal) {
switch(signal.getColor()) {
case TrafficSignal.RED: return Action.STOP;
case TrafficSignal.YELLOW:
// decide whether to stop or go
if (this.shouldGo())
return Action.INCREASE_SPEED;
else return Action.STOP;
case TrafficSignal.GREEN: // no change
return this.currentAction;
default: throw new IllegalArgumentException
("Invalid traffic color");}} // required
public void drive() {
TrafficSignal aSignal = ... ;
Action reaction = this.react(aSignal);
62. function Enumerizable(C)
1: W ← C /* seed the worklist with the input constants */
2: N ← ∅ /* the non-enumerizable set list, initially empty */
3: for all c ∈ C do
4: MakeSet(c) /* init the union-find data structure */
5: end for
6: while W ̸= ∅ do
7: /* remove an element from the worklist */
8: α ← e | e ∈ W
9: W ← W {α}
10: for all αctxt ∈ Contexts(α, P) do
11: if ¬isEnumerizableContext(α, αctxt ) then
α variable, eld, method
αctxt context in which α may occur
Figure 2. Formalism notation.
procedure Enumerize(F, P)
1: R ← Enumerizable(F)
2: R ← Unique(R) ∩ Distinct(R) ∩ Consistent(R)
3: for all T ∈ R do
4: Transform(T)
5: end for
Figure 3. Top-level enumerization algorithm.
refactoring. We also assume that we are able to statica
identify all references to candidate elds and transitively d
pendent program entities. This assumption could be inva
dated through the use of reection and custom class loade
Enumerization Approach
Editor's Notes
Today I will be discussing an automated approach to refactoring legacy Java software to utilize the new Java enumerated type language construct. This is joint work Jason Sawin and Dr. Atanas Rountev at the Ohio State University and is supported in part by the NSF.
Changing a method to accommodate a new parameter requires changing the method declaration for each method in the type hierarchy, examining other methods in the hierarchy to assure they are not being overridden, and altering each method invocation site scattered throughout the source code.
HashMap iterator is fail-safe while Hashtable enumerator isn't. If you change the map while iterating, you'll know.
With the emergence of Java’s 1.5 (Tiger) release came a rich set of new features including but not limited to generics, annotations, primitive boxing and unboxing, and the concentration of this work, type-safe enumerations.
Our focus today will be to highlight an automated, semantics-preserving approach based on declarative type inferencing for the migration of legacy Java code (in particular but not limited to 1.4) to take advantage of these new, highly desirable language enumeration constructs.
I will then proceed to discuss some experimental results from a research prototype of the tool on 17 large Java applications.
Oh, and by the way, the tool is currently in progress to be integrated with the standard distribution of Eclipse.
An enumerated (enum) type is a data type whose legal values consist of a fixed, closely related set of items known at compile time. They are typically used for comparisons in order to “parameterize” the behavior of the system. Values are commonly distinct from one another and possibly ordered in some preconceived way. And since it was not included up until the release of Java 5, developers, over the years, were forced to use certain “compensation patterns” to represent enum types in Java.
Although several of these compensation patterns exist, here is an instance of a particular pattern, one that has been labeled by the literature as the “standard” way to represent enumerated types in Java 1.4 and below. This pattern has been commonly referred to as the “int enum pattern,” however, since our tool does not discriminate against constants belonging to most primitive types, we will refer to it as the “weak enum pattern.” The term “weak” is used here to denote the pattern’s inherent lack of several key features as I will explain shortly.
Taking a look at our example, here we have a class representing a traffic light signal. The members of the class are as follows. There are three static final constant fields defined, RED, YELLOW, and GREEN, symbolizing the different colors of a traffic signal. Also notice that the constants are ordered akin to the order in which the signals typically appear. We also have a private instance variable called “color” representing the current color the traffic signal is displaying. And lastly, we have an accessor method called “getColor” which simply returns the current value of the preceding instance variable.
Almost immediately apparent is the significant lack of type safety inherent to this pattern. For instance, the field color may receive values from any legal integer outside the set of 0, 1, and 2. Furthermore, operations that are legal for integers may accidentally be applied to colors, such as addition, which may not make a whole lot of sense and possibly produce values outside the intended set of original values.
Another disadvantage of this pattern is that the constants are manually enumerated and its easy to see that such a task is error prone. In particular, a developer may accidentally assign the same value to two different constants unintentionally thereby mistakenly giving the same semantics to two different constants, an error that would not manifest itself until run time.
Yet another drawback is the pattern’s lack of namespacing. That is, by looking at this constant alone, it is unclear as to what RED is referring to. Is it the color of a traffic signal or is it the color of a matador's cape?
Last but not least, the pattern produces constants are brittle, that is, separate compilation is not supported. Since the value of the constant is in-lined into clients at compile time, changing their internal value not only requires recompilation of this class, but also recompilation of all clients. Such a situation would arise during software evolution when perhaps a new constant was to be added in between existing constants.
Now let’s take a look at how we can manually transform this particular instance of the weak enum pattern to instead utilize the new language enumeration constructed provided in Java 5 ...
First, let’s remove the static final integer constants and replace them with an equivalent language enumerated type called “Color.”
Next, since we changed the type of the constants and that there is a type dependency with the private instance variable “color,” we must change the declared type of this member from integer to the “Color” enumerated type we declared above.
Of course, since the color field has changed type, its associated assessor method must also be declared to return the new type of this field.
Let’s now examine some of the key features that our new language enumerated type offers over the weak enum pattern instance we saw previously. Notice that our color constants are now associated with their own type, specifically, TrafficSignal.Color.
As a consequence, we have improved the type safety of the code.
Also notice that we have forgone the need to manually enumerate the constants with internal primitive values. Language enumerated types in Java 5 instead utilize the well known “Singleton” pattern where each constant refers to a single memory location in the entire system. Further notice that although the primitive values have disappeared, we have preserved the ordering we had previously bestowed on the constants in that they are now in a so-called “natural” order, that is, they are ordered by the way they are listed in the new type declaration.
Moreover, language enumerated constructs must be properly prefixed by their enclosing type, thereby improving namespace. For instance, we know that red refers to a Traffic Signal color.
And last but not least, since language enumerated constants are reference types, their values, since they are determined at run time, are not in-lined into clients thereby supporting separate compilation.
Now that we have altered our Traffic Signal class to take advantage of the new language enumerated types offered in Java 1.5, let’s consider clients of the traffic signal class. What sorts of changes should be propagated to these clients? Here is a simple example where client code must be examined.
Here we have an “Automobile” class that is a client of “Traffic Signals.” It has a method named “react” that takes a reference to a traffic signal as input and returns the appropriate action this automobile should take dependent upon the color of the signal. So, let’s take a look at the contexts in which the signal is used.
Here’s a call to the signal’s color access method that appears in a switch statement. One nice, new feature of the enum construct is that it is compatible with switch statements. That is, previously, only integral types were allowed inside the switch expression, however, in Java 1.5, expressions evaluating to an enum type are also allowed, thus allowing for a more general switch statement.
Of course, we must also ensure that each case expression evaluates to one of three colors we defined earlier before we can do any transformation.
From a refactoring point of view, one stipulation is that the case statements inherit the namespace of the switch expression, so we must remove the prefix from each case statement.
As I mentioned earlier, the react method returns an automobile action that should be taken by this automobile dependent upon the color of the traffic single. Interestingly, the set of “automobile actions” constitute another, separate enum type participating in the weak enum pattern. Moving further up the automobile class, we see that automobile actions are similarly declared.
Also notice that there’s another constant named “MAX_SPEED” which has an almost identical declaration as the automobile actions above it, however, the connotation of this constant is very different from that of automobile actions. MAX_SPEED is what is known as a “named constant,” its a symbolic name for a particular threshold value. Another example of a named constant is java.lang.PI. You can imagine that such a value would appear in various mathematical operations which would not be directly compatible with enum types. As for MAX_SPEED In this context, is being used to denote the maximum acceleration of the automobile. As we will see, we don’t want to refactor these sorts of constants, and that distinguishing between these kinds of entities presents itself as one of the key challenges of an automated approach.
Just as we did for the traffic signal class, let’s examine the code for type dependent entities of our automobile actions. Here we see a instance variable named “currentAction” which is intended to represent the current action the automobile is performing. We see that it receives its value from one of the constants so we’ll mark this entity as “promising” in that it potentially could take on an enum type. We’ll have to further examine type dependent entities of “currentAction” in order to say for sure.
Here’s an example of an instance variable with a very similar declaration as the entity above, however, we definitely do not want to refactor this field as it is meant to represent the current acceleration of the automobile. Thus, its “internal value” has a very precise meaning and we do not want to remove from the code.
Now that we have identified another promising enum type, we more to our second category of contexts in which these entities appear, specifically return statements. Due to this context, notice that signatures should change. Furthermore, the type of the field current action should change since it is a possible return value.
Let’s now examine the changes required to transform automobile actions into language enumeration types. Since we are returning “Actions” we must now alter the return type of the method signature. Doing so requires further investigation as we will see shortly. The other changes are simpler in that we only need to add a prefix to each constant.
Notice that the field “currentAction” does not change since its declared type has already been altered as well as the appropriate method signature. That’s one thing that’s nice about this refactoring, the original source is type correct once the declarations of the entities that have been considered “safe” for enumerization has changed. I’ll discuss what it means for a program entity to be considered safe next.
We use a union-find data structure to track entity dependencies and to form the partitions.
Adaptation of a classic declarative type inferencing algorithm inductively defined in the Java grammar. Here is a snippet of the formalization of our algorithm.
Groups them into minimal sets s.t. each set must share the same enum type.
Natural ordering by original primitive values in order to preserve comparability semantics.
Column uses shows the total number of declaration sites that must be modified to accommodate the enumerization.
See technical report for a complete list of filtered contexts.
13% needs more sophisticated primitive value analysis.
Native array copying requires more sophisticated tracking of entities.