Get Enum Instance from Class<? extends Enum> using String value?
Solution 1
public static <T extends Enum<T>> T getInstance(final String value, final Class<T> enumClass) {
return Enum.valueOf(enumClass, value);
}
And the method is to be used as:
final Shape shape = getInstance("CAT", Shape.class);
Then again, you can always use
final Shape shape = Shape.valueOf("CAT");
which is a shortcut for
Enum.valueOf(Shape.class, "CAT");
Solution 2
We want to get the Method
object which reflects the valueOf
method of the passed-in Class
, which accepts a String
parameter; then invoke
it with no object (since it's static) and the supplied String parameter:
type.getDeclaredMethod("valueOf", String.class).invoke(null, value);
You will need to catch a boatload of different types of exceptions.
Solution 3
So here is the code being using Spring validation and works great for me. Full code given below.
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.ReportAsSingleViolation;
import javax.validation.constraints.NotNull;
@Documented
@Constraint(validatedBy = EnumValidatorImpl.class)
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@NotNull(message = "Value cannot be null")
@ReportAsSingleViolation
public @interface EnumValidator {
Class<? extends Enum<?>> enumClazz();
String message() default "Value is not valid";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Implementation of the above class:
import java.util.ArrayList;
import java.util.List;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class EnumValidatorImpl implements ConstraintValidator<EnumValidator, String> {
List<String> valueList = null;
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if(!valueList.contains(value.toUpperCase())) {
return false;
}
return true;
}
@Override
public void initialize(EnumValidator constraintAnnotation) {
valueList = new ArrayList<String>();
Class<? extends Enum<?>> enumClass = constraintAnnotation.enumClazz();
@SuppressWarnings("rawtypes")
Enum[] enumValArr = enumClass.getEnumConstants();
for(@SuppressWarnings("rawtypes")
Enum enumVal : enumValArr) {
valueList.add(enumVal.toString());
}
}
}
USAGE OF THE ABOVE ANNOTATION IS VERY SIMPLE
@JsonProperty("lead_id")
@EnumValidator( enumClazz=DefaultEnum.class,message="This error is coming from the enum class", groups = {Group1.class })
private String leadId;
Craig Otis
Updated on January 12, 2020Comments
-
Craig Otis over 4 years
I'm finding it difficult to put the exact question into words, so I'll just give an example.
I have two
Enum
types:enum Shape { CAT, DOG; } enum Color { BLUE, RED; }
I have a method:
public Object getInstance(String value, Class<?> type);
I would like to use the method like:
// someValue is probably "RED", and someEnumClass is probably Color.class Color c = getInstance(someValue, someEnumClass);
I've been having trouble determining exactly how to implement
getInstance()
. Once you know the exactEnum
class that you want to instantiate, it's easy:Color.valueOf("RED");
But how can this above line be accomplished with an unknown
Class
? (It is, however, known that thesomeEnumClass
is a subclass ofEnum
.)Thanks!