Skip to content
CMO & CTO
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

  • Digital Experience
    • Experience Strategy
    • Experience-Driven Commerce
    • Multi-Channel Experience
    • Personalization & Targeting
    • SEO & Performance
    • User Journey & Behavior
  • Marketing Technologies
    • Analytics & Measurement
    • Content Management Systems
    • Customer Data Platforms
    • Digital Asset Management
    • Marketing Automation
    • MarTech Stack & Strategy
    • Technology Buying & ROI
  • Software Engineering
    • Software Engineering
    • Software Architecture
    • General Software
    • Development Practices
    • Productivity & Workflow
    • Code
    • Engineering Management
    • Business of Software
    • Code
    • Digital Transformation
    • Systems Thinking
    • Technical Implementation
  • About
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

Enums in Java 5

Posted on July 28, 2007 By Luis Fernandez

I keep bumping into old int constants and bit masks, and each time I do, I hear a tiny voice saying use enums in Java 5 already.

Enums landed with Java 5 and they are more than a cute list of names. They are full blown types with behavior, and they make code read like what it means. If you come from the land of public static final int, this is a breath of fresh air. Tools are ready too. Eclipse Europa and recent NetBeans builds are happy with them, and the compiler does the right thing. What I like most is that enums are type safe by default. The compiler will not let you pass a status where a permission is expected, and that kills a whole class of silly bugs.

The simplest win is ditching numeric constants. Look at this tiny before and after. The old way makes you remember numbers and keep a comment nearby so you do not forget. The new way reads like plain English and the IDE offers autocompletion with zero setup.

// Old 1.4 style
public class OrderStatusOld {
    public static final int NEW = 0;
    public static final int PROCESSING = 1;
    public static final int SHIPPED = 2;
    public static final int CANCELED = 3;
}

// Java 5 enum
public enum OrderStatus {
    NEW, PROCESSING, SHIPPED, CANCELED
}

Switch works with enums too, and that makes the path from old code to a cleaner version pretty short. No more fall through surprises because you forgot a break while juggling integers.

void handle(OrderStatus status) {
    switch (status) {
        case NEW:
            notifyUser("We got your order");
            break;
        case PROCESSING:
            log("Packing items");
            break;
        case SHIPPED:
            updateTracking();
            break;
        case CANCELED:
            refund();
            break;
    }
}

Where enums really shine is when you give them state and behavior. Enums are classes. You can add fields, constructors, methods, even have each constant behave in a slightly different way. This replaces scattered if blocks with logic that lives right next to the thing it describes. It also makes unit tests cleaner, since you can exercise the behavior per constant and avoid magic values. Here is a small example with a priority that carries a weight and a label.

public enum Priority {
    LOW(1, "low"),
    MEDIUM(5, "medium"),
    HIGH(10, "high");

    private final int weight;
    private final String label;

    Priority(int weight, String label) {
        this.weight = weight;
        this.label = label;
    }

    public int weight() { return weight; }
    public String label() { return label; }

    @Override public String toString() {
        return label.toUpperCase();
    }
}

You can also define abstract methods and make each constant implement it. That pattern keeps branching out of callers and tucks it under the enum. Feels like a tiny strategy object that lives in the enum constant. It reads well and is quick to scan in code review.

public enum TrafficLight {
    RED {
        public boolean canGo() { return false; }
    },
    YELLOW {
        public boolean canGo() { return false; }
    },
    GREEN {
        public boolean canGo() { return true; }
    };

    public abstract boolean canGo();
}

And there is more in the box. The JDK comes with EnumSet and EnumMap, both built for speed and memory use when the keys are enums. If you are still packing flags into an int, do yourself a favor and move to EnumSet. Your future self will thank you when you read the code later.

EnumSet<OrderStatus> openStatuses =
        EnumSet.of(OrderStatus.NEW, OrderStatus.PROCESSING);

EnumMap<OrderStatus, String> labels =
        new EnumMap<>(OrderStatus.class);
labels.put(OrderStatus.NEW, "New");
labels.put(OrderStatus.SHIPPED, "Shipped");

A few tips from real code. Do not rely on ordinal. It is tempting to store the index in a database field, but that breaks when someone reorders constants. Store the name instead and map with valueOf. Also be careful when serializing enums across different class loaders. Names need to be stable. For human readable output, override toString, but keep name as the name you persist. That keeps pretty logs and safe persistence. If you need custom parsing, add a static method and do your mapping there.

// Safe persistence
String dbValue = status.name();
// Later
OrderStatus status = OrderStatus.valueOf(dbValue);

One more nice trick. Enums can implement interfaces. This is handy in places where you want different families of options plugged into the same code. Think of pricing strategies, date formats, or command verbs. Because these are plain classes, you can unit test them just like any other class and keep concerns tight.

public interface Command {
    String verb();
    void run();
}

public enum FileCommand implements Command {
    OPEN {
        public String verb() { return "open"; }
        public void run() { /* open file */ }
    },
    SAVE {
        public String verb() { return "save"; }
        public void run() { /* save file */ }
    }
}

If you are migrating old code, start small. Replace a bundle of constants with an enum, switch one API to accept the new type, and use a shim for callers that still send integers. The compiler will guide you to the call sites. Once that goes in, add behavior to the enum where you find repeated branching. Little by little, readability goes up, tests get simpler, and the code feels honest about the domain it models. That is the big win with enums in Java 5. They turn intent into types.

Right now a lot of teams are moving to Java 5 for generics and annotations. Enums ride along with that move and give you quick wins with low risk. They play nice with frameworks too. Spring deals with them without trouble, JPA implementations are catching up, and most logging setups print them cleanly. If you think about search keywords for your next rainy day refactor, put Enums in Java 5, EnumSet, and EnumMap on the list.


Try an enum today and drop one int constant file from your project.

Cleaner code is sometimes just a new type away.

Code Development Practices Software Engineering coding-practicesjavaspring

Post navigation

Previous post
Next post
  • Digital Experience (94)
    • Experience Strategy (19)
    • Experience-Driven Commerce (5)
    • Multi-Channel Experience (9)
    • Personalization & Targeting (21)
    • SEO & Performance (10)
  • Marketing Technologies (92)
    • Analytics & Measurement (14)
    • Content Management Systems (45)
    • Customer Data Platforms (4)
    • Digital Asset Management (8)
    • Marketing Automation (6)
    • MarTech Stack & Strategy (10)
    • Technology Buying & ROI (3)
  • Software Engineering (310)
    • Business of Software (20)
    • Code (30)
    • Development Practices (52)
    • Digital Transformation (21)
    • Engineering Management (25)
    • General Software (82)
    • Productivity & Workflow (30)
    • Software Architecture (85)
    • Technical Implementation (23)
  • 2025 (12)
  • 2024 (8)
  • 2023 (18)
  • 2022 (13)
  • 2021 (3)
  • 2020 (8)
  • 2019 (8)
  • 2018 (23)
  • 2017 (17)
  • 2016 (40)
  • 2015 (37)
  • 2014 (25)
  • 2013 (28)
  • 2012 (24)
  • 2011 (30)
  • 2010 (42)
  • 2009 (25)
  • 2008 (13)
  • 2007 (33)
  • 2006 (26)

Ab Testing Adobe Adobe Analytics Adobe Target AEM agile-methodologies Analytics architecture-patterns CDP CMS coding-practices content-marketing Content Supply Chain Conversion Optimization Core Web Vitals customer-education Customer Data Platform Customer Experience Customer Journey DAM Data Layer Data Unification documentation DXP Individualization java Martech metrics mobile-development Mobile First Multichannel Omnichannel Personalization product-strategy project-management Responsive Design Search Engine Optimization Segmentation seo spring Targeting Tracking user-experience User Journey web-development

©2025 CMO & CTO | WordPress Theme by SuperbThemes