Introduction
Converting an enum to a string is a fundamental operation in most programming languages. In Java, use .name() for the exact constant name or .toString() for a customizable representation. In C#, use .ToString() or nameof(). In Python, use .name or .value. In TypeScript, string enums are already strings. The reverse operation (string to enum) is equally important and uses Enum.valueOf() in Java, Enum.Parse() in C#, or bracket notation in TypeScript. Understanding the differences between name-based and value-based conversion prevents bugs in serialization, API responses, and database storage.
Java
1public enum Color {
2 RED, GREEN, BLUE;
3}
4
5// Enum to string
6Color color = Color.RED;
7String name = color.name(); // "RED" (always the constant name)
8String str = color.toString(); // "RED" (can be overridden)
9String ordinal = String.valueOf(color.ordinal()); // "0"
10
11// String to enum
12Color parsed = Color.valueOf("RED"); // Color.RED
13// Color.valueOf("red"); // IllegalArgumentException — case-sensitive!
14
15// Safe parsing
16public static Color fromString(String name) {
17 try {
18 return Color.valueOf(name.toUpperCase());
19 } catch (IllegalArgumentException e) {
20 return null; // or a default value
21 }
22}
1// Enum with custom string representation
2public enum Status {
3 ACTIVE("Active"),
4 INACTIVE("Inactive"),
5 PENDING_REVIEW("Pending Review");
6
7 private final String displayName;
8
9 Status(String displayName) {
10 this.displayName = displayName;
11 }
12
13 public String getDisplayName() {
14 return displayName;
15 }
16
17 @Override
18 public String toString() {
19 return displayName;
20 }
21
22 // Reverse lookup by display name
23 public static Status fromDisplayName(String name) {
24 for (Status status : values()) {
25 if (status.displayName.equalsIgnoreCase(name)) {
26 return status;
27 }
28 }
29 throw new IllegalArgumentException("Unknown status: " + name);
30 }
31}
32
33Status s = Status.PENDING_REVIEW;
34System.out.println(s.name()); // "PENDING_REVIEW"
35System.out.println(s.toString()); // "Pending Review"
36System.out.println(s.getDisplayName()); // "Pending Review"
C#
1public enum Color { Red, Green, Blue }
2
3// Enum to string
4Color color = Color.Red;
5string name = color.ToString(); // "Red"
6string name2 = Enum.GetName(typeof(Color), color); // "Red"
7string name3 = nameof(Color.Red); // "Red" (compile-time)
8
9// String to enum
10Color parsed = (Color)Enum.Parse(typeof(Color), "Red"); // Color.Red
11Color parsed2 = Enum.Parse<Color>("Red"); // C# 7.3+
12bool success = Enum.TryParse("Blue", out Color result); // true, result = Blue
13bool ci = Enum.TryParse("blue", ignoreCase: true, out Color r); // true
14
15// Enum to integer and back
16int value = (int)Color.Green; // 1
17Color fromInt = (Color)2; // Color.Blue
1// Enum with Description attribute
2using System.ComponentModel;
3
4public enum OrderStatus
5{
6 [Description("New Order")]
7 New,
8 [Description("In Progress")]
9 InProgress,
10 [Description("Shipped")]
11 Shipped
12}
13
14// Extension method to get Description
15public static string GetDescription(this Enum value)
16{
17 var field = value.GetType().GetField(value.ToString());
18 var attr = field.GetCustomAttribute<DescriptionAttribute>();
19 return attr?.Description ?? value.ToString();
20}
21
22Console.WriteLine(OrderStatus.InProgress.GetDescription()); // "In Progress"
Python
1from enum import Enum
2
3class Color(Enum):
4 RED = 1
5 GREEN = 2
6 BLUE = 3
7
8# Enum to string
9color = Color.RED
10print(color.name) # "RED"
11print(color.value) # 1
12print(str(color)) # "Color.RED"
13print(f"{color}") # "Color.RED"
14
15# String to enum
16parsed = Color["RED"] # Color.RED (by name)
17parsed = Color(1) # Color.RED (by value)
18
19# Safe parsing
20def parse_color(name: str) -> Color | None:
21 try:
22 return Color[name.upper()]
23 except KeyError:
24 return None
1# String enum (values are strings)
2class Status(str, Enum):
3 ACTIVE = "active"
4 INACTIVE = "inactive"
5 PENDING = "pending_review"
6
7# Works like a string in most contexts
8print(Status.ACTIVE.value) # "active"
9print(Status.ACTIVE == "active") # True (because of str mixin)
10print(f"Status: {Status.ACTIVE}") # "Status: Status.ACTIVE"
11
12# Reverse lookup by value
13status = Status("active") # Status.ACTIVE
TypeScript / JavaScript
1// Numeric enum
2enum Color {
3 Red, // 0
4 Green, // 1
5 Blue, // 2
6}
7
8// Enum to string
9const name: string = Color[Color.Red]; // "Red" (reverse mapping)
10const value: number = Color.Red; // 0
11
12// String enum (recommended)
13enum Status {
14 Active = "ACTIVE",
15 Inactive = "INACTIVE",
16 Pending = "PENDING",
17}
18
19const str: string = Status.Active; // "ACTIVE" (already a string)
20
21// String to enum
22function parseStatus(value: string): Status | undefined {
23 return Object.values(Status).includes(value as Status)
24 ? (value as Status)
25 : undefined;
26}
27
28// const enum (inlined at compile time, no reverse mapping)
29const enum Direction {
30 Up = "UP",
31 Down = "DOWN",
32}
Swift
1enum Planet: String {
2 case mercury = "Mercury"
3 case venus = "Venus"
4 case earth = "Earth"
5}
6
7// Enum to string
8let name = Planet.earth.rawValue // "Earth"
9let description = String(describing: Planet.earth) // "earth" (case name)
10
11// String to enum
12let planet = Planet(rawValue: "Earth") // Optional(Planet.earth)
13
14// CaseIterable for iteration
15enum Color: String, CaseIterable {
16 case red, green, blue
17}
18
19for color in Color.allCases {
20 print(color.rawValue) // "red", "green", "blue"
21}
Common Pitfalls
Case sensitivity in string-to-enum conversion: Color.valueOf("red") in Java throws IllegalArgumentException because the constant is RED. Always normalize case before parsing, or use a case-insensitive lookup method.
Confusing .name() and .toString() in Java: .name() always returns the exact constant name and cannot be overridden. .toString() can be overridden to return a custom string. For serialization and deserialization, use .name() for consistency.
Using ordinal values for persistence: Storing color.ordinal() (0, 1, 2) in a database breaks when enum constants are reordered or new values are inserted. Store the string name or an explicit value instead.
TypeScript numeric enums with reverse mapping confusion: Numeric enums create bidirectional mappings (Color[0] = "Red" and Color["Red"] = 0). Iterating Object.values(Color) returns both names and numbers. String enums do not have reverse mapping.
Python str(enum) not returning the value: str(Color.RED) returns "Color.RED", not "RED". Use Color.RED.name for the constant name or Color.RED.value for the assigned value. For JSON serialization, use .value or .name explicitly.
Summary
Java: .name() for constant name, .toString() for customizable display, valueOf() for parsing
C#: .ToString() for name, Enum.Parse<T>() for parsing, [Description] for display names
Python: .name for constant name, .value for assigned value, Color["RED"] for parsing
TypeScript: string enums are already strings; numeric enums use Color[value] for reverse mapping
Swift: .rawValue for the associated raw value, init?(rawValue:) for parsing
Store enum names (not ordinals) in databases to survive reordering and insertion of new values