[英]Java Generic Enum as a Parameter
所以我有几个定义如下的枚举。 我有一个使用枚举查找值的方法。
public enum MyEnum1
{
STRING1("My String1"),
STRING2("My String2"),
STRING3("My String3"),
STRINGLESS("String not found");
private String s;
private MyEnum1(String s) { this.s = s; }
public String getValue() { return s; }
}
public enum MyEnum2
{
STRING1("My String1"),
STRING2("My String2"),
STRING3("My String3"),
STRINGLESS("String not found");
private String s;
private MyEnum2(String s) { this.s = s; }
public String getValue() { return s; }
}
public class MyClass1
{
public static String getPlacement(String myString)
{
for (MyEnum1 a: MyEnum1.values())
if (myString.contains(a.toString()))
return a.getValue();
return MyEnum1.STRINGLESS.getValue();
}
}
public class MyClass2
{
public static String getPlacement(String myString)
{
for (MyEnum2 a: MyEnum2.values())
if (myString.contains(a.toString()))
return a.getValue();
return MyEnum2.STRINGLESS.getValue();
}
}
现在,我定义了5个枚举,所有的枚举都由相同的getPlacement方法处理,但是我必须使用ForE循环中的MyEnum2,MyEnum3 ...创建5个不同的MyClass类(MyClass2,MyClass3 ...),以使其实现。
我试过了...
public static String getPlacement(Enum e, String myString) {}
和
public static String getPlacement(Enum<?> e, String myString) {}
但都行不通。
我想将一个Enum作为参数传递给getPlacement方法,从而使我只能拥有一个MyClass类,该类可以处理5个不同的Enum。 这可能吗?
将这样的界面添加到您的代码中。
public interface Named {
String name();
}
让您所有的枚举都像
public enum MyEnum1 implements Named {...}
然后使用如下接口声明您的方法:
public static String getPlacement(Named enumValue, String myString) {}
在getPlacement()
方法内部,调用enumValue.name()
而不是toString()
,尽管您可以使用toString()进行完全相同的操作,但这取决于您在接口定义中使用的名称(可以按您的喜好命名,而不是必须Named
)。
顺便说一句,使用单个字母作为变量名通常被认为是不好的做法。
要保留getPlacement
的确切语义,可以执行以下操作:
interface StringValue {
String getValue();
}
enum MyEnum1 implements StringValue {
...
private String stringValue;
...
@Override
public String getValue() {
return stringValue;
}
}
static <E extends Enum<E> & StringValue>
String getPlacement(Class<E> enumClass, String inValue) {
for(E constant : enumClass.getEnumConstants()) {
if(inValue.contains(constant.toString()))
return constant.getValue();
}
return Enum.valueOf(enumClass, "STRINGLESS").getValue();
}
我不确定这里的确切语义对您是否真的很重要。 如果不是,则有更简单的方法。 如果您不需要contains
,则可以使用Enum#valueOf
。 如果可以重写toString
(因为也可以使用Enum#name
),则不需要接口。
而且,就像所有复杂的枚举情况一样,如果您不使用枚举,事情可能会简单得多。 具有私有构造函数和public static final
常量的final
类可以完成枚举无法完成的许多事情(例如从抽象超类继承...)。
Enum基类java.lang.Enum具有用于构造任意枚举实例的静态工厂方法valueOf(Class, String)
。 有了一点泛型魔术,您应该就能解决您的问题。
public enum MyEnum1 {
STRING1("MyEnum1 String1"),
STRING2("MyEnum1 String2"),
STRING3("MyEnum1 String3"),
STRINGLESS("MyEnum1 String not found");
private String s;
private MyEnum1(String s) { this.s = s; }
@Override
public String toString() { return s; }
}
public enum MyEnum2 {
STRING1("MyEnum2 String1"),
STRING2("MyEnum2 String2"),
STRING3("MyEnum2 String3"),
STRINGLESS("MyEnum2 String not found");
private String s;
private MyEnum2(String s) { this.s = s; }
@Override
public String toString() { return s; }
}
public static void main(String[] args) {
System.out.println(getPlacement(MyEnum1.class, "STRING1").name());
System.out.println(getPlacement(MyEnum2.class, "STRING3").name());
System.out.println(getPlacement(MyEnum2.class, "foobar").name());
}
public static <T extends Enum<T>> Enum<T> getPlacement(Class<T> clazz, String value) {
try {
return Enum.valueOf(clazz, value);
} catch (IllegalArgumentException e) {
return Enum.valueOf(clazz, "STRINGLESS");
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.