Opposite access to enums Consider I have many enums (Java) that looks somewhat like this:

@AllArgsConstructor
@Getter
public enum PopularPeriod {
  MONTHLY  ("MON"),
  BIMONTHLY ("BMN"),
  QUARTERLY  ("QTR"),
  SEMI_ANNUALLY  ("SMA"),
  ANNUALLY  ("ANL");

  private final String value;
}


Now, a usual use, I'd think, would be to get the enum object using its value (the string) - there's an input you're parsing and you want to turn the string into some nice objects that make the code more readable.

So I added this to the enum above - 

public static PopularPeriod fromString(String value) {
  for (PopularPeriod pp : PopularPeriod.values()) {
    if (pp.getValue().equalsIgnoreCase(value)) return pp;
  }

  return null;
}


(don't mind the returning of null the casing).
This works quite good. 
But if you have dozens of those enums - you need to write it for each one.

I tried approaches like adding something like this to a utility class -

public static &lt;T extends Enum&lt;T&gt;&gt; T safeEnumByValue(Class&lt;T&gt; enumType, Object value) { ... }


but there I don't know of the private field (value).

So I though of "implementing" an interface instead (as enum may not extend base classes), and make the search as a default method in the interface.

public interface IEnum&lt;T&gt; {
  T getValue();
}

@AllArgsConstructor
@Getter
public enum PopularPeriod implements IEnum&lt;String&gt; { ... }


and adding a default method in the interface - but that's impossible as I don't have the PopularPeriod.values() there to work with.

In the end, I combined the two approaches.
I have this method in a utility class:

public static &lt;T extends IEnum&gt; T safeEnumByValue(Class&lt;T&gt; enumType, Object value) {
  for (T enumConstant : enumType.getEnumConstants()) {
    if (enumConstant.getValue().equals(value)) return enumConstant;
  }

  return null;
}


Just got there.
It works.
I thought maybe I'd delete this question,but I would love to hear if there's any elegant way to do it.
There may be a more fundamental problem here beyond converting a string to enum.

By adding a fromString(String) into the enum and defining the format specific strings in the enum constructor, you are coupling the enum tightly to the data format and making it an integral part of the input parser. Your enum now has two responsibilities, being clearly in violation of the single responsibility principle

Instead you should implement a format specific converter that converts the string used in transport to the enum used in computing and make the enum as bare as possible.