从Class 使用String值?

我发现很难将确切的问题写成文字,所以我只想举个例子。

我有两种Enum类型:

 enum Shape { CAT, DOG; } enum Color { BLUE, RED; } 

我有一个方法:

 public Object getInstance(String value, Class type); 

我想用这样的方法:

 // someValue is probably "RED", and someEnumClass is probably Color.class Color c = getInstance(someValue, someEnumClass); 

我一直无法确定如何实现getInstance() 。 一旦知道要实例化的确切Enum类,就很容易:

 Color.valueOf("RED"); 

但是如何用一个未知的Class完成上述这一行呢? (但是,已知someEnumClassEnum的子类。)

谢谢!

  public static > T getInstance(final String value, final Class enumClass) { return Enum.valueOf(enumClass, value); } 

该方法用作:

 final Shape shape = getInstance("CAT", Shape.class); 

然后,你可以随时使用

 final Shape shape = Shape.valueOf("CAT"); 

这是一个捷径

 Enum.valueOf(Shape.class, "CAT"); 

我们想要获取Method对象,该对象反映传入的ClassvalueOf方法,该方法接受String参数; 然后invoke它没有对象(因为它是静态的)和提供的String参数:

 type.getDeclaredMethod("valueOf", String.class).invoke(null, value); 

您将需要捕获大量不同类型的exception。

所以这里是使用Springvalidation的代码,对我来说很有用。 完整代码如下。

 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> enumClazz(); String message() default "Value is not valid"; Class[] groups() default {}; Class[] payload() default {}; } 

上述课程的实施:

 import java.util.ArrayList; import java.util.List; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; public class EnumValidatorImpl implements ConstraintValidator { List 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(); Class> enumClass = constraintAnnotation.enumClazz(); @SuppressWarnings("rawtypes") Enum[] enumValArr = enumClass.getEnumConstants(); for(@SuppressWarnings("rawtypes") Enum enumVal : enumValArr) { valueList.add(enumVal.toString()); } } } 

使用上面的注释非常简单

  @JsonProperty("lead_id") @EnumValidator( enumClazz=DefaultEnum.class,message="This error is coming from the enum class", groups = {Group1.class }) private String leadId; 

既然你已经了解了你正在寻找什么课程,你可以问一下它是否知道你感兴趣的内容:

 public enum MyColor { RED ("red", Color.RED), BLUE ("blue", Color.BLUE), TAUPE ("brownish", new COLOR(80,64,77)); private final String _name; private final Color _color; MyColor(String name, Color color) { _name = name; _color = color; } public static Color parseColor(String colorName) { for (MyColor mc : MyColor.values()) { if (mc._name.equalsIgnoreCase(colorName)) return mc._color; } return null; } } 

但是,将字符串插入多个枚举中以寻找合适的内容会影响使用枚举的类型安全性。 如果你将“红色”映射到MyColor.REDNuclearThreatWarningLevel.RED那么你可能至少会得到错误的类。 在最坏的情况下,你可能会在你的地下掩体中停留6个月等待空气清除,当你想要的只是一辆漆成红色的车:)

如果可能的话,最好重新设计代码的这个区域,这样你就不必动态地将字符串转换为几个类之一的实例。 如果你扩展你的答案以包括你试图解决的问题,也许SO社区会有一些想法。