Как получить значение enum по строке в Java
Основной способ: метод valueOf()
В Java у каждого enum есть встроенный статический метод valueOf(String), который преобразует строку в соответствующий элемент перечисления. Он чувствителен к регистру и выбрасывает IllegalArgumentException, если строка не найдена.
String statusStr = "PROCESSING";
OrderStatus status = OrderStatus.valueOf(statusStr);
System.out.println(status); // PROCESSING
Проблема с регистром
Если строка приходит в другом регистре (например, "processing" или "Processing"), нужно её нормализовать. Самый простой способ — привести к верхнему регистру:
String userInput = "processing";
OrderStatus status = OrderStatus.valueOf(userInput.toUpperCase());
Безопасное преобразование с обработкой ошибок
Чтобы избежать исключений при невалидных строках, используйте try-catch:
public static OrderStatus safeValueOf(String value) {
try {
return OrderStatus.valueOf(value.toUpperCase());
} catch (IllegalArgumentException e) {
System.out.println("Неизвестный статус: " + value);
return OrderStatus.NEW; // значение по умолчанию
}
}
Лучшая практика: кастомный метод с Map
Для сложных случаев (например, когда строки не совпадают с именами enum) создайте статический Map внутри enum:
import java.util.HashMap;
import java.util.Map;
public enum OrderStatus {
NEW("новый"),
PROCESSING("в обработке"),
SHIPPED("отправлен"),
DELIVERED("доставлен"),
CANCELLED("отменён");
private final String displayName;
private static final Map<String, OrderStatus> BY_NAME = new HashMap<>();
static {
for (OrderStatus status : values()) {
BY_NAME.put(status.displayName.toLowerCase(), status);
BY_NAME.put(status.name().toLowerCase(), status);
}
}
OrderStatus(String displayName) {
this.displayName = displayName;
}
public String getDisplayName() {
return displayName;
}
public static OrderStatus fromString(String value) {
if (value == null || value.trim().isEmpty()) {
throw new IllegalArgumentException("Статус не может быть пустым");
}
OrderStatus result = BY_NAME.get(value.trim().toLowerCase());
if (result == null) {
throw new IllegalArgumentException("Неизвестный статус: " + value);
}
return result;
}
}
Использование:
OrderStatus s1 = OrderStatus.fromString("в обработке"); // PROCESSING
OrderStatus s2 = OrderStatus.fromString("SHIPPED"); // SHIPPED
OrderStatus s3 = OrderStatus.fromString("отменён"); // CANCELLED
Дополнительные советы
- Null safety: Всегда проверяйте входную строку на null
- Stream API: Для простых случаев можно использовать стримы:
public static Optional<OrderStatus> findByString(String value) {
return Arrays.stream(values())
.filter(s -> s.name().equalsIgnoreCase(value))
.findFirst();
}
Этот подход возвращает Optional, что явно показывает — результат может отсутствовать.
Выбирайте метод в зависимости от ваших потребностей. Для простых случаев достаточно valueOf() с toUpperCase(), для production-кода лучше использовать кастомный метод с Map — он быстрее и гибче.
Альтернативный подход: использование аннотации @JsonCreator (для Jackson)
Если вы работаете с JSON (например, в REST API или при десериализации), самый удобный способ — добавить аннотацию @JsonCreator из библиотеки Jackson. Это позволяет автоматически преобразовывать строки из JSON в enum без ручного кода:
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;
public enum OrderStatus {
NEW, PROCESSING, SHIPPED, DELIVERED, CANCELLED;
@JsonCreator
public static OrderStatus fromString(String value) {
if (value == null) return null;
for (OrderStatus status : values()) {
if (status.name().equalsIgnoreCase(value)) {
return status;
}
}
throw new IllegalArgumentException("Unknown status: " + value);
}
@JsonValue
public String toValue() {
return name().toLowerCase();
}
}
Теперь при десериализации JSON строка "processing" автоматически преобразуется в OrderStatus.PROCESSING, а при сериализации enum превратится в строку "processing". Это особенно удобно для Spring Boot приложений, где Jackson используется "из коробки".
Для простых случаев без внешних библиотек используйте первый ответ — он универсален и не требует дополнительных зависимостей.